CodeChef submission 79964 (C++ 4.0.0-8) plaintext list. Status: AC, problem NSUDOKU, contest AUGMINI. By triplem (Stephen Merriman), 2009-08-24 14:58:34.
#include <iostream> #include <cstdlib> using namespace std; int grid[900][900]; bool preset[900][900]; int cc[3][900][900]; int L,N; int numstates; char output[50000000]; char input[50000000]; long long sizeatend; int starttime; int outpos=0, inpos=0, numcharsin; void writeint(int a) { if (a==0) { output[outpos++]='0'; return; } char tmp[10]; int tp = 0; while (a) {tmp[tp++]=a%10;a/=10;} while (tp--) { output[outpos++]=tmp[tp]+'0'; } } int getint() { while (input[inpos]<'0' || input[inpos]>'9') inpos++; int ret = 0; while (inpos<numcharsin && input[inpos]>='0' && input[inpos]<='9') ret = 10*ret+input[inpos++]-'0'; return ret; } typedef struct State { long long parts[15]; State() {for (int i=0; i<15; i++) parts[i]=0;} void update(int val) { // printf("before: %I64d\n",parts[val/61]); // printf("Adding 1LL<<%d\n",val); parts[val/61]|=1LL<<(val%61); // printf("after: %I64d\n",parts[val/61]); } void reset() { for (int i=0; i<15; i++) parts[i]=0; } void print() { for (int i=0; i<numstates; i++) } }; int getscore() { int score = 0; static bool found[3][900][900]; for (int i=0; i<L; i++) for (int j=0; j<L; j++) { found[0][i][grid[i][j]-1]=true; found[1][j][grid[i][j]-1]=true; found[2][(i/N)*N+(j/N)][grid[i][j]-1]=true; } for (int i=0; i<L; i++) for (int k=0; k<L; k++) for (int j=0; j<3; j++) if (!found[j][i][k]) score++; return score; } State states[3][900]; void update(int x, int y) { cc[0][x][grid[x][y]-1]++; states[0][x].update(grid[x][y]-1); cc[1][y][grid[x][y]-1]++; states[1][y].update(grid[x][y]-1); cc[2][N*(x/N)+y/N][grid[x][y]-1]++; states[2][N*(x/N)+y/N].update(grid[x][y]-1); } int getbest(int x, int y, int type) { // printf("At %d,%d\n",x,y); State *one = &states[0][x]; State *two = &states[1][y]; State *three = &states[2][N*(x/N)+y/N]; long long stophere = (1LL<<61)-1; for (int i=0; i<numstates; i++) { long long stop = (i==numstates-1?sizeatend:stophere); long long tmp = one->parts[i]|two->parts[i]|three->parts[i]; if (tmp==stop) continue; for (int j=0; j<61 && 61*i+j<L; j++) { if (tmp&1) {tmp/=2;continue;} return 61*i+j+1; tmp/=2; } } for (int i=0; i<numstates; i++) { long long stop = (i==numstates-1?sizeatend:stophere); long long tmp1 = one->parts[i]|two->parts[i]; long long tmp2 = one->parts[i]|three->parts[i]; long long tmp3 = two->parts[i]|three->parts[i]; if (tmp1==stop && tmp2==stop && tmp3==stop) continue; long long tmp; if (tmp1!=stop) tmp=tmp1; else if (tmp2!=stop) tmp=tmp2; else tmp = tmp3; for (int j=0; j<61 && 61*i+j<L; j++) { if (tmp&1) {tmp/=2;continue;} return 61*i+j+1; tmp/=2; } } if (type==100) { for (int i=0; i<numstates; i++) { long long stop = (i==numstates-1?sizeatend:stophere); long long tmp1 = one->parts[i]; long long tmp2 = two->parts[i]; long long tmp3 = three->parts[i]; if (tmp1==stop && tmp2==stop && tmp3==stop) continue; long long tmp; if (tmp1!=stop) tmp=tmp1; else if (tmp2!=stop) tmp=tmp2; else tmp = tmp3; for (int j=0; j<61 && 61*i+j<L; j++) { if (tmp&1) {tmp/=2;continue;} return 61*i+j+1; tmp/=2; } } //fprintf(stderr,"\n\n\n\n\n\n"); } return 0; } int perm[810000]; void print() { for (int i=0; i<L; i++) { for (int j=0; j<L; j++) { } } } int getdelta(int x, int y1, int y2, bool doit) { if (grid[x][y1]==grid[x][y2]) return 0; // suppose we switch (x,y1) and (x,y2) int delta = 0; // row x is unchanged // column y1 // we increase the grid[x][y2] count, decrease the grid[x][y1] coun if (cc[1][y1][grid[x][y2]-1]==0) {delta++; if (doit) cc[1][y1][grid[x][y2]-1]++; } if (cc[1][y1][grid[x][y1]-1]==1) {delta--; if (doit) cc[1][y1][grid[x][y1]-1]--; } // column y2 if (cc[1][y2][grid[x][y2]-1]==1) {delta--; if (doit) cc[1][y2][grid[x][y2]-1]--; } if (cc[1][y2][grid[x][y1]-1]==0) {delta++; if (doit) cc[1][y2][grid[x][y1]-1]++; } if (y1/N!=y2/N) { if (cc[2][N*(x/N)+y1/N][grid[x][y2]-1]==0) {delta++;if (doit) cc[2][N*(x/N)+y1/N][grid[x][y2]-1]++; } if (cc[2][N*(x/N)+y1/N][grid[x][y1]-1]==1) {delta--;if (doit) cc[2][N*(x/N)+y1/N][grid[x][y1]-1]--; } if (cc[2][N*(x/N)+y2/N][grid[x][y2]-1]==1) {delta--;if (doit) cc[2][N*(x/N)+y2/N][grid[x][y2]-1]--; } if (cc[2][N*(x/N)+y2/N][grid[x][y1]-1]==0) {delta++;if (doit) cc[2][N*(x/N)+y2/N][grid[x][y1]-1]++; } } if (doit) {int tmp = grid[x][y1]; grid[x][y1] = grid[x][y2]; grid[x][y2] = tmp; } return delta; } int getdelta2(int x, int y1, int y2, bool doit) { if (grid[y1][x]==grid[y2][x]) return 0; // suppose we switch (x,y1) and (x,y2) int delta = 0; // row x is unchanged // column y1 // we increase the grid[y2][x] count, decrease the grid[y1][x] coun if (cc[0][y1][grid[y2][x]-1]==0) {delta++; if (doit) cc[0][y1][grid[y2][x]-1]++; } if (cc[0][y1][grid[y1][x]-1]==1) {delta--; if (doit) cc[0][y1][grid[y1][x]-1]--; } // column y2 if (cc[0][y2][grid[y2][x]-1]==1) {delta--; if (doit) cc[1][y2][grid[y2][x]-1]--; } if (cc[0][y2][grid[y1][x]-1]==0) {delta++; if (doit) cc[1][y2][grid[y1][x]-1]++; } if (y1/N!=y2/N) { if (cc[2][N*(x/N)+y1/N][grid[y2][x]-1]==0) {delta++;if (doit) cc[2][N*(x/N)+y1/N][grid[y2][x]-1]++; } if (cc[2][N*(x/N)+y1/N][grid[y1][x]-1]==1) {delta--;if (doit) cc[2][N*(x/N)+y1/N][grid[y1][x]-1]--; } if (cc[2][N*(x/N)+y2/N][grid[y2][x]-1]==1) {delta--;if (doit) cc[2][N*(x/N)+y2/N][grid[y2][x]-1]--; } if (cc[2][N*(x/N)+y2/N][grid[y1][x]-1]==0) {delta++;if (doit) cc[2][N*(x/N)+y2/N][grid[y1][x]-1]++; } } if (doit) {int tmp = grid[y1][x]; grid[y1][x] = grid[y2][x]; grid[y2][x] = tmp; } return delta; } int score; void doswitch(int x, int y, int z) { int delta = getdelta(x,y,z,false); if (delta>0) { getdelta(x,y,z,true); #ifndef ONLINE_JUDGE score -= delta; #endif } } void doswitch2(int x, int y, int z) { int delta = getdelta2(x,y,z,false); if (delta>0) { getdelta2(x,y,z,true); #ifndef ONLINE_JUDGE score -= delta; #endif } } int randperm2[900]; void checkbrute() { #ifndef ONLINE_JUDGE score = getscore(); #endif while (true) { int xx; int x = randperm2[xx]; for (int y1=0; y1<L; y1++) { if (preset[x][y1]) continue; for (int y2=y1+1; y2<L && y1/N==y2/N; y2++) { if (preset[x][y2]) continue; doswitch(x,y1,y2); }} for (int y1=0; y1<L; y1++) { if (preset[y1][x]) continue; for (int y2=y1+1; y2<L && y1/N==y2/N; y2++) { if (preset[y2][x]) continue; doswitch2(x,y1,y2); }} } if (xx!=L) break; } } int main() { N = getint(); int K = getint(); L = N*N; for (int i=0; i<L; i++) randperm2[i]=i; random_shuffle(randperm2,randperm2+L); int LL = L*L; for (int i=0; i<LL; i++) perm[i]=i; random_shuffle(perm,perm+LL); /* for (int i=0; i<LL; i++) { int m = i/L; int n = i%L; int x = m/N; int y = m%N; x += N*(n/N); y += N*(n%N); perm[i] = x*L+y; } */ numstates = (L+60)/61; int leftover = L%61; sizeatend = (1LL<<leftover)-1; // printf("numstates: %d\n",numstates); for (int i=0; i<K; i++) { int x = getint(); int y = getint(); int d = getint();x--;-y--; grid[x][y]=d; preset[x][y]=true; update(x,y); } for (int i=0; i<LL; i++) { int x = perm[i]%L; int y = perm[i]/L; if (grid[x][y]==0) { grid[x][y]=getbest(x,y,0); if (grid[x][y]) update(x,y); } } for (int i=0; i<L; i++) for (int j=0; j<L; j++) { if (grid[i][j]==0) { grid[i][j]=getbest(i,j,100); update(i,j); } } checkbrute(); #ifndef ONLINE_JUDGE { } #endif for (int i=0; i<L; i++) { for (int j=0; j<L; j++) { writeint(grid[i][j]); output[outpos++]=' '; } output[outpos++]='\n'; } }
Comments

