#define _CRT_SECURE_NO_DEPRECATE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define all(v) v.begin(),v.end() #define INF 2000000001 #define SQSZ 2 const int SQLM = SQSZ - 1; using namespace std; typedef long long ll; typedef unsigned long long ull; //typedef unsigned char byte; typedef long double ld; const ld epsylon = 1e-9; typedef unsigned int ui; inline long double get_time(){ return (long double)clock()/CLOCKS_PER_SEC; }; ld start_time, end_time; struct Command { int a,s,d,f,g; }; struct Color { int r, g, b; Color(int r, int g, int b):r(r), g(g), b(b) {} Color(): r(255), g(255), b(255) {} }; Color mix(Color& a, Color& b) { return Color((a.r+b.r)/2,(a.g+b.g)/2,(a.b+b.b)/2); } int SQR(int x) {return x*x;} int MIN(int x, int y) { return x < y ? x : y; } int MAX(int x, int y) { return x < y ? y : x; } int diff(Color& a, Color& b) { return SQR(a.r-b.r)+SQR(a.g-b.g)+SQR(a.b-b.b); } int diffMix(Color& a, Color& mix1, Color& mix2) { return SQR(a.r - (mix1.r + mix2.r)/2) + SQR(a.g - (mix1.g + mix2.g)/2) + SQR(a.b - (mix1.b + mix2.b)/2); } int diffMix2(Color& a, Color& mix11, Color& mix12, Color& mix2) { return SQR(a.r - ((mix11.r + mix12.r)/2 + mix2.r)/2) + SQR(a.g - ((mix11.g + mix12.g)/2 + mix2.g)/2) + SQR(a.b - ((mix11.b + mix12.b)/2 + mix2.b)/2); } int n, k; Color pic[300][300]; Color buf; Color newPic[300][300]; vector palette; Color middleColor(int xFrom, int xTo, int yFrom, int yTo) { int r = 0, g = 0, b = 0; for (int i = xFrom; i < xTo; ++i) { for (int j = yFrom; j < yTo; ++j) { r += pic[i][j].r; g += pic[i][j].g; b += pic[i][j].b; } } int divisor = (xTo-xFrom)*(yTo-yFrom); r /= divisor; g /= divisor; b /= divisor; return Color(r,g,b); } // returns // 0 if no change soft, // 1 if no change hard, // 2 if on picture soft, // 3 if on picture hard, // 4 if on palette soft, // 5 if on palette hard int chooseBest(int x, int y, Color curActive, int& xclr, int& yclr, int& palIdx) { Color target = middleColor(x,x+SQSZ,y,y+SQSZ); int bd1 = diffMix(target, curActive, newPic[x][y]); int bd2 = diff(target, curActive); int bestDiff, res; if (bd1 < bd2) { bestDiff = bd1; res = 0; } else { bestDiff = bd2; res = 1; } for (int i = 0; i <= x; i+=SQSZ) { for (int j = 0; j < n; j+=SQSZ) { if (i==x && j==y) break; int dif1 = diffMix(target, curActive, newPic[i][j]); int dif2 = diffMix2(target, curActive, newPic[i][j], newPic[x][y]); if (dif1 < dif2 && dif1 < bestDiff) { res = 3; xclr = i; yclr = j; bestDiff = dif1; } else if (dif2 < dif1 && dif2 < bestDiff) { res = 2; xclr = i; yclr = j; bestDiff = dif2; } if (i < x - 50) { j += 9*SQSZ; } } } for (int i = 0; i < k; ++i) { int dif1 = diffMix(target, palette[i], curActive); int dif2 = diffMix2(target, palette[i], curActive, newPic[x][y]); if (dif1 < dif2 && dif1 < bestDiff) { bestDiff = dif1; res = 5; palIdx = i; } else if (dif2 < dif1 && dif2 < bestDiff) { bestDiff = dif2; res = 4; palIdx = i; } } return res; } int chooseBest2(int x, int y, Color curActive, int& xclr, int& yclr, int& palIdx) { Color target = middleColor(x,x+SQSZ,y,y+SQSZ); int bd1 = diffMix(target, curActive, newPic[x][y]); int bd2 = diff(target, curActive); int bestDiff, res; if (bd1 < bd2) { bestDiff = bd1; res = 0; } else { bestDiff = bd2; res = 1; } int I = MIN(x+50,n); int J = MIN(y+50,n); int JSTART = MAX(0,y-50); for (int i = MAX(0,x-50); i < I; i+=SQSZ) { for (int j = JSTART; j < J; j+=SQSZ) { if (i==x && j==y) break; int dif1 = diffMix(target, curActive, newPic[i][j]); int dif2 = diffMix2(target, curActive, newPic[i][j], newPic[x][y]); if (dif1 < dif2 && dif1 < bestDiff) { res = 3; xclr = i; yclr = j; bestDiff = dif1; } else if (dif2 < dif1 && dif2 < bestDiff) { res = 2; xclr = i; yclr = j; bestDiff = dif2; } } } for (int i = 0; i < k; ++i) { int dif1 = diffMix(target, palette[i], curActive); int dif2 = diffMix2(target, palette[i], curActive, newPic[x][y]); if (dif1 < dif2 && dif1 < bestDiff) { bestDiff = dif1; res = 5; palIdx = i; } else if (dif2 < dif1 && dif2 < bestDiff) { bestDiff = dif2; res = 4; palIdx = i; } } return res; } void solve() { vector commands; Color curActive; for (int x = 0; x < n; x += SQSZ) { for (int y = 0; y < n; y += SQSZ) { if (commands.size() > 89950 || get_time() - start_time > 4.5) { break; } int clrX, clrY, palIdx; int bestClrChoice = chooseBest(x,y,curActive,clrX,clrY,palIdx); if (bestClrChoice == 0) { // no chane soft newPic[x][y] = mix(curActive,newPic[x][y]); Command cmd;cmd.a=4;cmd.s=x;cmd.d=y;cmd.f=x+SQLM;cmd.g=y+SQLM; commands.push_back(cmd); } else if (bestClrChoice == 1) { // no change hard newPic[x][y] = curActive; Command cmd;cmd.a=3;cmd.s=x;cmd.d=y;cmd.f=x+SQLM;cmd.g=y+SQLM; commands.push_back(cmd); } else if (bestClrChoice == 2) { // on picture soft curActive = mix(curActive,newPic[clrX][clrY]); newPic[x][y] = mix(curActive, newPic[x][y]); Command cmd1; cmd1.a=2;cmd1.s=clrX;cmd1.d=clrY; Command cmd2; cmd2.a=4;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } else if (bestClrChoice == 3) { // on picture hard curActive = mix(curActive,newPic[clrX][clrY]); newPic[x][y] = curActive; Command cmd1; cmd1.a=2;cmd1.s=clrX;cmd1.d=clrY; Command cmd2; cmd2.a=3;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } else if (bestClrChoice == 4) { // on palette soft curActive = mix(curActive, palette[palIdx]); newPic[x][y] = mix(curActive, newPic[x][y]); Command cmd1; cmd1.a=1;cmd1.s=palIdx; Command cmd2; cmd2.a=4;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } else if (bestClrChoice == 5) { // on palette hard curActive = mix(curActive, palette[palIdx]); newPic[x][y] = curActive; Command cmd1; cmd1.a=1;cmd1.s=palIdx; Command cmd2; cmd2.a=3;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } } } // second pass for (int x = 0; x < n; x += SQSZ) { for (int y = 0; y < n; y += SQSZ) { if (commands.size() > 89950 || get_time() - start_time > 4.5) { break; } int clrX, clrY, palIdx; int bestClrChoice = chooseBest2(x,y,curActive,clrX,clrY,palIdx); if (bestClrChoice == 0) { // no chane soft newPic[x][y] = mix(curActive,newPic[x][y]); Command cmd;cmd.a=4;cmd.s=x;cmd.d=y;cmd.f=x+SQLM;cmd.g=y+SQLM; commands.push_back(cmd); } else if (bestClrChoice == 1) { // no change hard newPic[x][y] = curActive; Command cmd;cmd.a=3;cmd.s=x;cmd.d=y;cmd.f=x+SQLM;cmd.g=y+SQLM; commands.push_back(cmd); } else if (bestClrChoice == 2) { // on picture soft curActive = mix(curActive,newPic[clrX][clrY]); newPic[x][y] = mix(curActive, newPic[x][y]); Command cmd1; cmd1.a=2;cmd1.s=clrX;cmd1.d=clrY; Command cmd2; cmd2.a=4;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } else if (bestClrChoice == 3) { // on picture hard curActive = mix(curActive,newPic[clrX][clrY]); newPic[x][y] = curActive; Command cmd1; cmd1.a=2;cmd1.s=clrX;cmd1.d=clrY; Command cmd2; cmd2.a=3;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } else if (bestClrChoice == 4) { // on palette soft curActive = mix(curActive, palette[palIdx]); newPic[x][y] = mix(curActive, newPic[x][y]); Command cmd1; cmd1.a=1;cmd1.s=palIdx; Command cmd2; cmd2.a=4;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } else if (bestClrChoice == 5) { // on palette hard curActive = mix(curActive, palette[palIdx]); newPic[x][y] = curActive; Command cmd1; cmd1.a=1;cmd1.s=palIdx; Command cmd2; cmd2.a=3;cmd2.s=x;cmd2.d=y;cmd2.f=x+SQLM;cmd2.g=y+SQLM; commands.push_back(cmd1); commands.push_back(cmd2); } } } printf("%d\n", commands.size()); for (int i = 0; i < commands.size(); ++i) { Command c = commands[i]; if (c.a==1)printf("1 %d\n",c.s); else if (c.a==2)printf("2 %d %d\n", c.s, c.d); else if (c.a==3)printf("3 %d %d %d %d\n", c.s, c.d, c.f, c.g); else if (c.a==4)printf("4 %d %d %d %d\n", c.s, c.d, c.f, c.g); } } int main() { freopen("drawing.in","r",stdin); freopen("drawing.out","w",stdout); start_time = get_time(); //program scanf("%d %d\n", &n, &k); for (int i = 0; i < k; ++i) { Color c; scanf("%d %d %d\n", &c.r, &c.g, &c.b); palette.push_back(c); } for (int color = 0; color < 3; ++color) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (color == 0) { scanf("%d", &pic[i][j].r); } else if (color == 1) { scanf("%d", &pic[i][j].g); } else { scanf("%d", &pic[i][j].b); } } } } solve(); //end program end_time=get_time()-start_time; cerr << "End time: " << end_time << endl; return 0; }