标签:code while class ase solution ref following show numbers
题意:有一个N*M的方格板,现在要在上面的每个方格上涂颜色,有K种颜色,每种颜色分别涂c[1]次、c[2]次……c[K]次,c[1]+c[2]+……+c[K]=N*M
要求每个方格的颜色与其上下左右均不同,如果可以输出YES,并且输出其中的一种涂法,如果不行,输出NO;
思路:暴力搜索,但是这样会超时,可以在搜索中加入剪枝:对于剩余的方格数res,以及当前剩余的颜色可涂数必须满足(res+1)/2>=c[i]
否则在当前情况下继续向下搜得不到正确涂法;
代码如下:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int N,K,M; int c[30]; int mp[10][10]; int check(int x,int y,int k) { int f=1; if(mp[x-1][y]==k) f=0; if(mp[x][y-1]==k) f=0; return f; } int cal(int x,int y) { if(x>N) return 1; int res=(N-x)*M+M-y+2; ///剩余方格数+1 ; for(int i=1;i<=K;i++) if(res/2<c[i]) return 0; ///剪枝,某种颜色剩余方格数>(剩余方格数+1)/2 肯定不对; for(int i=1;i<=K;i++) { int f=0; if(c[i]&&check(x,y,i)){ mp[x][y]=i; c[i]--; if(y==M) f=cal(x+1,1); else f=cal(x,y+1); c[i]++; } if(f) return 1; } return 0; } int main() { int T,Case=1; cin>>T; while(T--) { scanf("%d%d%d",&N,&M,&K); for(int i=1;i<=K;i++) scanf("%d",&c[i]); printf("Case #%d:\n",Case++); if(!cal(1,1)) { puts("NO"); continue; } puts("YES"); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) printf("%d%c",mp[i][j],(j==M)?‘\n‘:‘ ‘); } return 0; }
HDU 5113--Black And White(搜索+剪枝)
标签:code while class ase solution ref following show numbers
原文地址:http://www.cnblogs.com/chen9510/p/7077871.html