http://acm.pku.edu.cn/JudgeOnline/problem?id=1162
Код:
#include <iostream> using namespace std; typedef int Coordinates; struct BasicBlock; struct BasicBlock { int n; // number of blocks Coordinates p1, p2, p3; // block coordinates }; struct BlockSet { int n; // number of blocks bool o[4096]; // if the corrisponding coordinates is occupided by a block }; int cur[3]; Coordinates pos; BasicBlock bb[106] = {{4,256,512,513}, {4,16,17,18}, {4,256,272,528}, {4,1,2,18}, {4,16,32,48}, {4,1,16,17}, {4,1,2,16}, {4,16,17,32}, {4,15,16,31}, {4,240,241,256}, {4,1,16,272}, {4,240,255,256}, {4,256,272,288}, {4,16,32,288}, {4,255,256,257}, {4,1,2,257}, {4,224,240,256}, {4,1,16,256}, {4,1,257,273}, {4,1,2,3}, {4,256,512,768}, {4,16,256,272}, {4,1,256,257}, {4,1,17,33}, {4,256,512,528}, {4,1,2,256}, {4,1,2,17}, {4,240,256,272}, {4,256,257,512}, {4,1,17,18}, {4,16,272,288}, {4,255,256,511}, {4,256,257,273}, {4,256,271,272}, {4,1,256,272}, {4,1,17,256}, {4,256,272,273}, {4,1,240,256}, {4,240,256,257}, {4,15,16,272}, {4,255,256,272}, {4,16,256,257}, {4,16,17,273}, {4,15,16,271}, {4,1,241,257}, {4,16,272,273}, {4,1,15,16}, {4,14,15,16}, {4,16,32,256}, {4,1,257,513}, {4,256,511,512}, {4,1,256,512}, {4,240,256,512}, {4,239,240,256}, {4,15,16,32}, {4,256,272,512}, {4,16,271,272}, {4,256,257,272}, {4,240,256,496}, {4,1,257,258}, {4,1,255,256}, {4,16,17,33}, {4,16,255,256}, {4,1,16,257}, {4,239,255,256}, {4,1,17,273}, {4,16,17,256}, {4,15,16,256}, {4,256,257,513}, {4,16,240,256}, {4,255,256,271}, {4,254,255,256}, {4,241,256,257}, {4,1,2,258}, {4,16,17,272}, {4,1,17,257}, {4,16,31,32}, {4,1,16,32}, {4,16,32,33}, {4,16,272,528}, {4,256,257,258}, {4,16,32,272}, {4,255,256,512}, {4,256,496,512}, {4,16,256,512}, {4,15,16,17}, {3,1,256,0}, {3,1,16,0}, {3,240,256,0}, {3,16,272,0}, {3,255,256,0}, {3,16,17,0}, {3,256,257,0}, {3,15,16,0}, {3,1,257,0}, {3,16,256,0}, {3,256,272,0}, {3,1,17,0}, {3,256,512,0}, {3,1,2,0}, {3,16,32,0}, {2,1,0,0}, {2,256,0,0}, {2,16,0,0}, {1,0,0,0}, {1,0,0,0}}; int best; // best possible solution int cbest; // current best solution BlockSet bs; void Slove(int level) { if ( cbest==best ) return; if ( (bs.n+3)/4 + level >= cbest ) return; if ( bs.n==0 ) { cbest = level; return; } // find the block with the minimum index pos = (cur[0]<<8) + (cur[1]<<4) + cur[2]; while ( !bs.o[pos] ) { cur[2]++; if ( cur[2]==8 ) { cur[2] = 1; cur[1]++; if ( cur[1]==8 ) { cur[1] = 1; cur[0]++; } } pos = (cur[0]<<8) + (cur[1]<<4) + cur[2]; } // try each building block for ( BasicBlock *end=&(bb[105]), *i=bb; i<end; i++) { if ( bs.o[pos+i->p1] && bs.o[pos+i->p2] && bs.o[pos+i->p3] ) { // can place int x =cur[0], y = cur[1], z = cur[2], bakpos = pos; bs.o[pos] = bs.o[pos+i->p1] = bs.o[pos+i->p2] = bs.o[pos+i->p3] = false; // place bs.n -= i->n; Slove(level+1); // recursion cur[0] = x; cur[1] = y; cur[2] = z; pos = bakpos; bs.o[pos] = bs.o[pos+i->p1] = bs.o[pos+i->p2] = bs.o[pos+i->p3] = true; // undo place bs.n += i->n; } } } int main() { int i, j, k, l; for ( i=0; i<4096; i++) bs.o[i] = false; cin>>bs.n; best = (bs.n+3)/4; for ( l=0; l<bs.n; l++) { cin>>i>>j>>k; bs.o[(i<<8)+(j<<4)+k] = true; } cur[0] = cur[1] = cur[2] = 1; cbest = 100; Slove(0); cout<<cbest; return 0; }