DFS+剪枝...
在每次DFS前,当前棋盘的格子数量的一半小于一种颜色的数量时就剪掉
4 1 5 2 4 1 3 3 4 1 2 2 4 2 3 3 2 2 2 3 2 3 2 2 2
Case #1: NO Case #2: YES 4 3 4 2 1 2 4 3 4 Case #3: YES 1 2 3 2 3 1 Case #4: YES 1 2 2 3 3 1
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,k;
int mp[6][6];
struct CC
{
int num,color;
}c[30];
int color[30];
int ccc[30];
bool cmp(CC a,CC b)
{
return a.num<b.num;
}
bool flag;
bool inside(int x,int y)
{
if((x>=0&&x<n) && (y>=0&&y<m)) return true;
return false;
}
bool check(int x,int y,int c)
{
if(inside(x+1,y)) if(mp[x+1][y]==c) return false;
if(inside(x-1,y)) if(mp[x-1][y]==c) return false;
if(inside(x,y+1)) if(mp[x][y+1]==c) return false;
if(inside(x,y-1)) if(mp[x][y-1]==c) return false;
return true;
}
bool vis[30];
bool dfs(int x,int y,int cnt)
{
if(flag==true) return true;
if(x==n+1||cnt==0)
{
flag=true;
return true;
}
for(int i=1;i<=k;i++)
{
if(ccc[i]>(cnt+1)/2) return false;
}
for(int i=0;i<n*m;i++)
{
if(vis[i]==true) continue;
if(check(x,y,color[i])==true)
{
vis[i]=true;
mp[x][y]=color[i];
ccc[color[i]]--;
int ny=y+1,nx=x;
if(ny>=m) {ny=0; nx++;}
dfs(nx,ny,cnt-1);
if(flag==true) return true;
ccc[color[i]]++;
mp[x][y]=0;
vis[i]=false;
}
}
return false;
}
int main()
{
int T_T,cas=1;
scanf("%d",&T_T);
while(T_T--)
{
memset(mp,0,sizeof(mp));
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<k;i++)
{
int x;
scanf("%d",&x);
c[i].num=x;
c[i].color=i+1;
ccc[i+1]=x;
}
sort(c,c+k,cmp);
printf("Case #%d:\n",cas++);
if(c[k-1].num>(((n+1)/2)*((m+1)/2)+(n/2)*(m/2)))
{
puts("NO"); continue;
}
int pos=0;
for(int i=0;i<k;i++)
{
int t=c[i].num;
int cc=c[i].color;
while(t--)
{
color[pos++]=cc;
}
}
flag=false;
memset(vis,false,sizeof(vis));
dfs(0,0,n*m);
if(flag)
{
puts("YES");
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
printf("%d%c",mp[i][j],(j==m-1)?'\n':' ');
}
else puts("NO");
}
return 0;
}
HDOJ 5113 Black And White DFS+剪枝
原文:http://blog.csdn.net/ck_boss/article/details/41632143