注意到,只要在搜索过程中出现一种颜色大于剩下格子/2,必然不用继续向下搜索。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int d[105][105],c[105]; 6 int n,m,k,temp; 7 int judge(int x,int y,int i) 8 { 9 if (y==1&&x==1) return 1; 10 if (x==1) 11 if (i==d[x][y-1]) return 0; 12 else return 1; 13 if (y==1) 14 if (i==d[x-1][y]) return 0; 15 else return 1; 16 if (i==d[x-1][y]||i==d[x][y-1]) return 0; 17 else return 1; 18 } 19 void dfs(int x,int y) 20 { 21 int i,j; 22 if (temp) return; 23 int step=(n-x)*m+m-y; 24 for (i=1;i<=k;i++) 25 if (c[i]>step/2+1) return; 26 if (x>n){ 27 temp=1; 28 printf("YES\n"); 29 for (i=1;i<=n;i++) 30 { 31 for (j=1;j<m;j++) 32 printf("%d ",d[i][j]); 33 printf("%d\n",d[i][m]); 34 } 35 return; 36 } 37 for (i=1;i<=k;i++) 38 if (c[i]&&judge(x,y,i)) 39 { 40 c[i]--; 41 d[x][y]=i; 42 if (y==m) dfs(x+1,1); 43 else dfs(x,y+1); 44 c[i]++; 45 d[x][y]=-1; 46 } 47 return; 48 } 49 int main() 50 { 51 int T,t,i; 52 scanf("%d",&T); 53 for (t=1;t<=T;t++) 54 { 55 scanf("%d%d%d",&n,&m,&k); 56 for (i=1;i<=k;i++) 57 scanf("%d",&c[i]); 58 memset(d,-1,sizeof(d)); 59 printf("Case #%d:\n",t); 60 temp=0; dfs(1,1); 61 if (!temp) printf("NO\n"); 62 } 63 }