CodeChef submission 108891 (C++ 4.0.0-8) plaintext list. Status: TLE, problem HX, contest OCT09. By keshav_57 (Keshav Dhandhania), 2009-10-11 14:55:01.
// TO DO // Think of something which is 'global' // Like start from someplace with greater concentration of larger numbers // Check if repeating flip_two() will help, or make a queue out of this as well #include<iostream> #include<fstream> #include<queue> #include<cstring> #include<algorithm> using namespace std; #define sz 2010 #define INF 100000000.0 #define block 2 int n; float q[sz][sz]; bool b[sz][sz]; float sum[sz][sz]; float SCORE[sz][sz]; float SCOREc[sz][sz]; int nx[7]; int ny[2][7]; float qdp[sz][sz]; float cost[sz][(1<<block)]; int prev[sz][(1<<block)]; float sum3[sz][sz]; void modify(int &i, int &j) { for (int k = 0; k < 6; k++) if (b[i][j]==b[i+nx[k]][j+ny[(i&1)][k]]) SCORE[i+nx[k]][j+ny[(i&1)][k]] += q[i][j]; else SCORE[i+nx[k]][j+ny[(i&1)][k]] -= q[i][j]; } void modify3(int &i, int &j) { for (int k = 0; k < 3; k++) if (b[i][j]==b[i+nx[k]][j+ny[(i&1)][k]]) SCORE[i+nx[k]][j+ny[(i&1)][k]] += q[i][j]; else SCORE[i+nx[k]][j+ny[(i&1)][k]] -= q[i][j]; } void input() { char str[100000]; int l = 0; float d; for (int i = 1; i <= n; i++) { l = 0; for (int j = 1; j <= n; j++) { d = 1.0; q[i][j] += d*(str[l]-'0'); while (1) { l++; if (str[l] == ' ' || str[l] == '\0') break; else if (str[l] >= '0' && str[l] <= '9') { d /= 10.0; q[i][j] += (str[l]-'0')*d; } } l++; } } } void output() { char str[10000]; str[2*n] = '\0'; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) str[2*(j-1)] = '0' + (b[i][j]?1:0); } } void init() { nx[1] = nx[2] = -1; nx[4] = nx[5] = 1; ny[1][1] = ny[1][5] = -1; ny[0][2] = ny[0][4] = 1; ny[1][0] = ny[0][0] = -1; ny[1][3] = ny[0][3] = 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 0; k < 6; k++) { if (k==3) sum3[i][j] = sum[i][j]; sum[i][j] += q[i+nx[k]][j+ny[(i&1)][k]]; } } void score (int i, int j) { SCORE[i][j] = 0.0; for (int k = 0; k < 6; k++) if (b[i+nx[k]][j+ny[(i&1)][k]]==b[i][j]) SCORE[i][j] += q[i+nx[k]][j+ny[(i&1)][k]]; } void score3 (int &i, int j, float &r1, float &r2) { r1 = 0.0; for (int k = 0; k < 3; k++) if (b[i+nx[k]][j+ny[(i&1)][k]]==b[i][j]) r1 += q[i+nx[k]][j+ny[(i&1)][k]]; r2 = sum3[i][j] - r1; } void scoreref3 (int &i, int &j, float &r1, float &r2) { r1 = 0.0; for (int k = 0; k < 3; k++) if (b[i+nx[k]][j+ny[(i&1)][k]]==b[i][j]) r1 += q[i+nx[k]][j+ny[(i&1)][k]]; r2 = sum3[i][j] - r1; } void scoreref (int &i, int &j) { SCORE[i][j] = 0.0; for (int k = 0; k < 6; k++) if (b[i+nx[k]][j+ny[(i&1)][k]]==b[i][j]) SCORE[i][j] += q[i+nx[k]][j+ny[(i&1)][k]]; } void flip_one_queue() { float r1, r2; queue <int> x; queue <int> y; int px, py; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { scoreref(i, j); if (sum[i][j]-SCORE[i][j] < SCORE[i][j]) { b[i][j] = !b[i][j]; SCORE[i][j] = sum[i][j]-SCORE[i][j]; modify3(i,j); for (int k = 0; k < 3; k++) { x.push(i+nx[k]); y.push(j+ny[(i&1)][k]); } // the rest three are later, so they are automatically checked; dont push them; } } while (!x.empty()) { px = x.front(); py = y.front(); x.pop(); y.pop(); if (px < 1 || px > n || py < 1 || py > n) continue; if (sum[px][py]-SCORE[px][py] < SCORE[px][py]) { SCORE[px][py] = sum[px][py]-SCORE[px][py]; b[px][py] = !b[px][py]; modify(px,py); for (int k = 0; k < 6; k++) { x.push(px+nx[k]); y.push(py+ny[(px&1)][k]); } } } } void flip_one_queue2() { float r1, r2; queue <int> x; queue <int> y; int px, py; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if (sum[i][j]-SCORE[i][j] < SCORE[i][j]) { b[i][j] = !b[i][j]; SCORE[i][j] = sum[i][j]-SCORE[i][j]; modify(i,j); for (int k = 0; k < 3; k++) { x.push(i+nx[k]); y.push(j+ny[(i&1)][k]); } // the rest three are later, so they are automatically checked; dont push them; } } while (!x.empty()) { px = x.front(); py = y.front(); x.pop(); y.pop(); if (px < 1 || px > n || py < 1 || py > n) continue; if (sum[px][py]-SCORE[px][py] < SCORE[px][py]) { SCORE[px][py] = sum[px][py]-SCORE[px][py]; b[px][py] = !b[px][py]; modify(px,py); for (int k = 0; k < 6; k++) { x.push(px+nx[k]); y.push(py+ny[(px&1)][k]); } } } } void dp() { int rem = n%block; int width = n + (rem?block-rem:0); int bitmask[(1<<block)]; bitmask[0] = 0; for (int i = 1; i < (1<<block); i++) bitmask[i] = (bitmask[i-1]^(i&(-i))); float cur; float r1, r2; int start, end; float addi; int i, j, k; for (int c = 0; c < (width/block); c++) { cost[0][0] = 0.0; start = c*block + 1; end = start + 1; for (i = 1; i <= n; i++) { qdp[i][start] = q[i][start]; qdp[i][end] = q[i][end]; } for (i = 1; i <= n+1; i++) { addi = 0.0; cur = 0.0; b[i][start] = b[i][end] = false; b[i-1][start] = ((1&j)?true:false); b[i-1][end] = ((2&j)?true:false); scoreref3(i,start,r1,r2); cur += r1*qdp[i][start]; scoreref3(i,end,r1,r2); cur += r1*qdp[i][end]; if (i&1) if (!b[i+1][start-1]) addi = q[i][j]*q[i+1][start-1]; if (cost[i][0] > cost[i-1][j]+cur+addi) { cost[i][0] = cost[i-1][j]+cur+addi; prev[i][0] = j; } { if (k&1) { scoreref3(i,start,r1,r2); b[i][start] ^= 1; cur += qdp[i][start]*(r2-r1); } else { scoreref3(i,end,r1,r2); b[i][end] ^= 1; cur += qdp[i][end]*(r2-r1); } addi = (((i&1)&&(b[i+1][start-1]^(bitmask[k]&1)))?q[i][j]*q[i+1][start-1]:0.0); if (cost[i][bitmask[k]] > cost[i-1][j]+cur+addi) { cost[i][bitmask[k]] = cost[i-1][j]+cur+addi; prev[i][bitmask[k]] = j; } } } int now = 0; for (i = n; i >= 1; i--) { now = prev[i+1][now]; for (int j = 0; j < block; j++) if ((1<<j)&now) b[i][start+j] = true; else b[i][start+j] = false; } } } void flip_two() { float af, bf, cf, df; int tempi, tempj; bool v; if (n < 1851) { for (int i = 2; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 0; k < 3; k++) { v = (b[i][j]==b[i+nx[k]][j+ny[(i&1)][k]]); if ((sum[i][j] - SCORE[i][j] - (!v?q[i+nx[k]][j+ny[(i&1)][k]]:0.0))*q[i][j] + (sum[i+nx[k]][j+ny[(i&1)][k]] - SCORE[i+nx[k]][j+ny[(i&1)][k]] - (!v?q[i][j]:0.0))*q[i+nx[k]][j+ny[(i&1)][k]] < (SCORE[i][j] - (v?q[i+nx[k]][j+ny[(i&1)][k]]:0.0))*q[i][j] + (SCORE[i+nx[k]][j+ny[(i&1)][k]] - (v?q[i][j]:0.0))*q[i+nx[k]][j+ny[(i&1)][k]]) { b[i][j] = !b[i][j]; b[i+nx[k]][j+ny[(i&1)][k]] = !b[i+nx[k]][j+ny[(i&1)][k]]; modify(i,j); tempi = i+nx[k]; tempj = j+ny[(i&1)][k]; modify(tempi,tempj); scoreref(i,j); scoreref(tempi,tempj); } } } else { for (int i = 1; i <= n; i++) for (int j = 2; j <= n; j++) { if ((sum[i][j] - SCORE[i][j] - (!v?q[i][j-1]:0.0))*q[i][j] + (sum[i][j-1] - SCORE[i][j-1] - (!v?q[i][j]:0.0))*q[i][j-1] < (SCORE[i][j] - (v?q[i][j-1]:0.0))*q[i][j] + (SCORE[i][j-1] - (v?q[i][j]:0.0))*q[i][j-1]) { b[i][j] = !b[i][j]; b[i][j-1] = !b[i][j-1]; modify(i,j); tempj = j-1; modify(i,tempj); scoreref(i,j); score(i,tempj); } } } } int main() { input(); init(); dp(); flip_one_queue(); if (n < 1951) { flip_two(); flip_one_queue2(); } output(); return 0; } /* int main () { char test_str[15] = "FC .txt\0"; char test_str2[15] = "9FC .txt\0"; double sc = 0.0, sc2 = 0.0; ofstream result; result.open("R9FlipTwo2.txt"); for (int test = 0; test < 10; test++) { sc = 0.0; n = 0; memset(q, 0, sizeof(q)); memset(b, 0, sizeof(b)); memset(sum, 0, sizeof(sum)); memset(qdp, 0, sizeof(qdp)); memset(prev, 0, sizeof(prev)); memset(cost, 0, sizeof(cost)); memset(sum3, 0, sizeof(sum3)); test_str[2] = test_str2[3] = test+'0'; freopen(test_str, "r", stdin); freopen(test_str2, "w", stdout); printf("\n"); MAIN(); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) sc += q[i][j-1]*q[i][j]*((b[i][j-1]==b[i][j])?1.0:0.0) + q[i-1][j]*q[i][j]*((b[i-1][j]==b[i][j])?1.0:0.0) + q[i-1][(i%2?j-1:j+1)]*q[i][j]*((b[i-1][(i%2?j-1:j+1)]==b[i][j])?1.0:0.0); sc2 += sc; result << sc << endl; fclose(stdin); fclose(stdout); } sc2 /= 10.0; result << endl << sc2 << endl; result.close(); return 0; } */ // 1421158.892623
Comments

