#include #include #include #include #include #define MAXM 100 #define MAXN 100 #define eps 0.01 //eroarea de propagare //propagation error int m,n,a[MAXM+2][MAXN+2],sol[MAXM+2][MAXN+2],valfin; long double t,x[MAXN+2],b[MAXN+2],b1[MAXN+2],b2[MAXN+2],tt[MAXN+2]; long double huge A1[MAXN+2][MAXN+2], huge A[MAXN+2][MAXN+2], huge tmp[MAXN+2][MAXN+2]; void read(FILE *fi) { int i,j; fscanf(fi,"%d%d",&m,&n); memset(a,0,sizeof(a)); for(i=1;i<=m;i++) for(j=1;j<=n;j++) fscanf(fi,"%d",&(a[i][j])); } int isinteger(long double x) { long double y=fabs(x-(int)x); if(y0) return (int)(x+0.5); else return (int)(x-0.5); } int LUPdesc(long double huge A[MAXN+2][MAXN+2],int P[MAXN+2],int n) //returneaza rangul matricei caracteristice //[P][A]=[L][U] //return the rank of the characteristic matrix { int i,j,k,r; long double p; for(i=1;i<=n;i++) P[i]=i; for(k=1;k<=n;k++) { p=0.0; for(i=k;i<=n;i++) if(fabsl(A[i][k])>p) p=fabsl(A[i][k]), r=i; if(p<0.000001) return k-1; //Matrice singulara - sistem nedeterminat //singular matrix - undetermined system j=P[k]; P[k]=P[r]; P[r]=j; for(i=1;i<=n;i++) p=A[k][i], A[k][i]=A[r][i], A[r][i]=p; for(i=k+1;i<=n;i++) { A[i][k]/=A[k][k]; for(j=k+1;j<=n;j++) A[i][j]-=A[i][k]*A[k][j]; } } return n; } int LUPsol(long double huge A[MAXN+2][MAXN+2],long double b[MAXN+2],int P[MAXN+2],int n,long double x[MAXN+2]) //intoarce 0 daca apar numere fractionare, 1 daca avem solutie //returns 0 for fractional numbers, 1 if we have solution { int i,j; long double y[MAXN+2],suma; for(i=1;i<=n;i++) { suma=0.0; for(j=1;j=1;i--) { suma=0.0; for(j=i+1;j<=n;j++) suma+=A[i][j]*x[j]; x[i]=(y[i]-suma)/A[i][i]; if(!isinteger(x[i])) return 0; } return 1; } void solve() { int i,j,k,nn; int pi[MAXN+2]; //calculeaza prima linie a solutiei //sistem de n ec. cu n necunoscute //care sunt cant. care se adauga la celulele de sus //sistemul este: [A][x]=[b], unde [A]=A2,[b]=b si [x]=x //in prima faza, calculam [P][A]=[L][U] //compute the first line of solution //system of n ec. with n unknows //which are the quantities which we add to the up cells (?) //the system is: [A][x]=[b], where [A]=A2,[b]=b si [x]=x //in first phase, we compute [P][A]=[L][U] _fmemset(A1,0,sizeof(A1)); _fmemset(A,0,sizeof(A)); for(i=1;i<=n;i++) A[i][i]=1; for(k=2;k<=m+1;k++) { for(j=1;j<=n;j++) for(i=1;i<=n;i++) A1[j][i]=-A1[j][i]-A[j-1][i]-A[j][i]-A[j+1][i]; //schimba randurile intre ele //swap rows _fmemcpy(tmp,A,sizeof(tmp)); _fmemcpy(A,A1,sizeof(A)); _fmemcpy(A1,tmp,sizeof(A1)); } nn=LUPdesc(A,pi,n); //acum, pt. valfin de la 0 la 1000 incercam sa obtinem un sistem //cu rezultate intregi //now, for valfin from 0 to 1000 we try to obtain a system with integer results for(valfin=0;valfin<=1000;valfin++) { //calcul [b] memset(b1,0,sizeof(b1)); memset(b2,0,sizeof(b2)); for(k=2;k<=m+1;k++) { for(j=1;j<=n;j++) b1[j]=valfin-b1[j]-b2[j-1]-b2[j]-b2[j+1]-a[k-1][j]; memcpy(tt,b2,sizeof(tt)); memcpy(b2,b1,sizeof(b2)); memcpy(b1,tt,sizeof(b1)); } memcpy(b,b2,sizeof(b)); for(i=1;i<=n;i++) b[i]=-b[i]; //verificam daca avem solutie //check for solution if(LUPsol(A,b,pi,nn,x)) break; } assert(valfin!=1001);//nu avem solutie - imposibil //no solution - impossible //calculeaza matricea sol //compute sol memset(sol,0,sizeof(sol)); for(i=1;i<=nn;i++) sol[1][i]=integer(x[i]),printf("%Lf\n",x[i]); for(;i<=n;i++) sol[1][i]=0; //valoare arbitrara pt. ca sistemul este nedeterminat //arbitrary value because we have an undetermined system for(i=2;i<=m;i++) for(j=1;j<=n;j++) sol[i][j]=valfin-a[i-1][j]-sol[i-2][j]-sol[i-1][j-1]-sol[i-1][j]-sol[i-1][j+1]; } void write(FILE *fo) { int i,j,nmodif=0,k; for(i=1;i<=m;i++) for(j=1;j<=n;j++) if(sol[i][j]!=0) nmodif++; fprintf(fo,"%d\n%d\n",valfin,nmodif); for(i=1;i<=m;i++) for(j=1;j<=n;j++) if(sol[i][j]!=0) fprintf(fo,"%d %d %d\n",i,j,sol[i][j]); } void main() { read(fopen("rubik.in","rt")); solve(); write(fopen("rubik.out","wt")); }