当前位置: 代码迷 >> 综合 >> HDU 5113 Black And White (DFS+剪枝)*
  详细解决方案

HDU 5113 Black And White (DFS+剪枝)*

热度:30   发布时间:2023-11-15 12:50:14.0

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5113

#include<bits/stdc++.h>
using namespace std;#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
const int mod=1e9+7;
const int maxn=1e5+4;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:给定k种颜色和其颜色的个数,
和一个二维平面,问是否存在一种涂色方案,
使得相邻两个颜色不同,k种颜色总数和二维平面格数一样。题目分析:由于范围很小,直接暴力搜索即可,
我这次的搜索自我感觉思维是超级精简了呢~QAQ
但是还是少了个剪枝操作T_T。。。被wa了。
首先是搜索的逻辑,我们只要安排当前维护好的二维平面中,
当前点左方和上方不冲突的颜色即可,其正确性感觉和dp思维比较像。
然后就是剪枝。。。get到一个点就是:剩余格数/2如果小于某个颜色数,
那么必然对于这个颜色来说会有相邻的相同,这样的剪枝逻辑,
大体就是考虑了极端情况吧,充分利用相邻性。'
时间复杂度:O(x^25*T+剪枝),,能过。。
*/
int n,m,k,flag;
int a[30],b[6][6];
void dfs(int pos){///考虑剪枝if(flag) return ;if(pos==n*m){flag=1;return ;}rep(i,0,k) if( (n*m-pos+1)/2 < a[i] ) return ;///剪枝int tn=pos/m,tm=pos%m;rep(i,0,k) if(a[i]){if(flag) return ;if(tn-1>=0&&b[tn-1][tm]==i+1) continue;if(tm-1>=0&&b[tn][tm-1]==i+1) continue;a[i]--,b[tn][tm]=i+1;dfs(pos+1);a[i]++;}
}int main(){int t;scanf("%d",&t);for(int ca=1;ca<=t;ca++){scanf("%d%d%d",&n,&m,&k);rep(i,0,k) scanf("%d",&a[i]);printf("Case #%d:\n",ca);flag=0,dfs(0);///搜索if(!flag) puts("NO");else{puts("YES");rep(i,0,n) rep(j,0,m) printf("%d%c",b[i][j],j==m-1?'\n':' ');}}return 0;
}