http://acm.pku.edu.cn/JudgeOnline/problem?id=1069
Код:
#include <iostream> #include <string.h> #include <stdlib.h> using namespace std; const int maxn=100; int ed; int n,h; int num; int size[11]; int dir[2*maxn+1][2*maxn+1],done[2*maxn+1][2*maxn+1]; short ok[maxn][maxn][11]; struct vy{ int left,right; }verge[11]; int com(const void *a,const void *b) { return *(int *)a-*(int *)b; } void init() { memset(size,0,sizeof(size)); memset(dir,0,sizeof(dir)); memset(done,0,sizeof(done)); memset(verge,0,sizeof(verge)); ed=0; cin>>n; int t; cin>>t; num=0; int i; for (i=1;i<=t;i++) { int k; cin>>k; int j; for(j=1;j<=num && size[j]!=k;j++); if (j>num) { num++; size[num]=k; } } size[0]=0; qsort(size,num+1,sizeof(size[0]),com); } void printout() { if (ed) cout<<"YES"<<endl; else cout<<"NO"<<endl; } void chose() { int i,j; for (i=1;i<=h;i++) { for (j=verge[i].left+1;j<=verge[i].right;j++) { dir[i][j]=-dir[i][j-1]; done[i][j]=0; } done[i][verge[i].left]=0; } for (i=1;i<=h;i++) { for (j=verge[i].left;j<=verge[i].right;j++) { int k; for (k=1;k<=num;k++) { if (dir[i][j]==1) { ok[i][j][k]=1; int x=j,y=j; int lm; for (lm=1;lm<=size[k];lm++) { if (x<verge[i+lm-1].left || y>verge[i+lm-1].right || i+lm-1>h) {ok[i][j][k]=0; break;} x--; y++; } } if (dir[i][j]==-1){ ok[i][j][k]=1; int x=j,y=j+size[k]*2-2; int lm; for (lm=1;lm<=size[k];lm++) { if (x<verge[i+lm-1].left || y>verge[i+lm-1].right || i+lm-1>h) {ok[i][j][k]=0;break;} x++; y--; } } } } } } void make_tri() { h=n; int i,j; for (i=1;i<=h;i++) { verge[i].left=maxn-i+1; verge[i].right=maxn+i-1; dir[i][verge[i].left]=1; } chose(); } void make_lin() { h=n; int i,j; for (i=1;i<=h;i++) { verge[i].left=maxn-n-i+1; verge[i].right=maxn+n-i; dir[i][verge[i].left]=1; } chose(); } void make_ti() { h=n; int i,j; for (i=1;i<=h;i++) { verge[i].left=maxn-n-i+1; verge[i].right=maxn+n+i-1; dir[i][verge[i].left]=1; } chose(); } void make_liu() { h=2*n; int i,j; for (i=1;i<=n;i++) { verge[i].left=maxn-n-i+1; verge[i].right=maxn+n+i-1; dir[i][verge[i].left]=1; } for (i=n+1;i<=h;i++) { verge[i].left=verge[2*n-i+1].left; verge[i].right=verge[2*n-i+1].right; dir[i][verge[i].left]=-1; } chose(); } void dfs(int x,int y) { if (ed) return; if (y>verge[x].right) { if (x>=h) {ed=1;return;} dfs(x+1,verge[x+1].left); return; } if (done[x][y]) {dfs(x,y+1);return;} int k; for (k=1;k<=num;k++) { if (!ok[x][y][k]) break; if (ed) break; int bi=size[k],bj=verge[x+size[k]-1].right+1; if (dir[x][y]==1) { int i,j; int able=1; int l,r; l=y; r=y; for (i=1;i<=size[k];i++) { for (j=l;j<=r;j++) { if (done[i+x-1][j]) { able=0; bi=i; bj=j; break; } else done[i+x-1][j]=1; } if (!able) break; l--; r++; } if (able) dfs(x,y+1); l=r=y; for (i=1;i<=bi;i++) { for (j=l;j<=r;j++) { if (i==bi && j==bj) break; done[x+i-1][j]=0; } l--; r++; } } else { int i,j; int able=1; int l=y,r=y+2*size[k]-2; for (i=1;i<=size[k];i++) { for (j=l;j<=r;j++) { if (done[i+x-1][j]) { able=0; bi=i; bj=j; break; } else done[i+x-1][j]=1; } if (!able) break; l++; r--; } if (able) dfs(x,y+1); l=y; r=y+2*size[k]-2; for (i=1;i<=bi;i++) { for (j=l;j<=r;j++) { if (i==bi && j==bj) break; done[i+x-1][j]=0; } l++; r--; } } } } void work() { ed=0; if (!ed) { make_tri(); dfs(1,verge[1].left); } if (!ed) { make_lin(); dfs(1,verge[1].left); } if (!ed) { make_ti(); dfs(1,verge[1].left); } if (!ed) { make_liu(); dfs(1,verge[1].left); } } int main() { int cases; cin>>cases; while (cases--) { init(); work(); printout(); } return 0; }