hdu 4127 Flood-it! 搜索

http://acm.hdu.edu.cn/showproblem.php?pid=4127

模擬題

染色時候,選擇格數較多的。然後迭代加深搜索,再考慮還剩下多少顏色,就可以減枝減過去了。確實很難的一道搜索。。。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
const int INF = 10000;
using namespace std;
int n;
struct Grid{
	char g[8][8];
	bool vis[8][8];
	int sum[6];
	int cur;
	vector<int> block[6];
	Grid(){
		cur=0;
		memset(vis,0,sizeof(vis));
	}
	int check(){
		int ans=0;
		for(int i=0;i<6;i++)if(sum[i])ans++;
		return ans;
	}
	void paint(int c){
		cur=c;
		for(int i=0;i<block[cur].size();i++){
			flood(block[cur][i]/8,block[cur][i]%8);
		}
		block[cur].clear();
	}
	void flood(int x,int y){
		if(vis[x][y])return;
		if(g[x][y]!=cur){block[g[x][y]].push_back(x*8+y);return;}
		sum[cur]--;
		vis[x][y]=true;
		
		if(x-1>=0)flood(x-1,y);
		if(x+1<n)flood(x+1,y);
		if(y-1>=0)flood(x,y-1);
		if(y+1<n)flood(x,y+1);
	}
	vector<int> get_seq(){
		vector<int> ans;
		bool v[6]={0};
		for(int i=0;i<6;i++){
			int u=-1;
			int m=0;
			for(int j=0;j<6;j++){
				if(!v[j]&&block[j].size()){
					if(block[j].size()>m){
						u=j;
						m=block[j].size();
					}
				}
			}
			if(u==-1)break;
			ans.push_back(u);
			v[u]=true;
		}
		return ans;
	}
};
int limit;
int d;
int ans;
bool dfs(Grid &a){
	if(a.check()==0){
		ans=min(d,ans);
		return true;
	}
	if(d+a.check()>=limit)return false;
	vector<int> seq=a.get_seq();
	for(int i=0;i<seq.size();i++){
		Grid b=a;
		b.paint(seq[i]);
		d++;
		if(dfs(b))return true;
		d--;
	}
}
int main(){
	while(~scanf("%d",&n)){
		if(n==0)break;
		Grid a;
		memset(a.vis,0,sizeof(a.vis));
		memset(a.sum,0,sizeof(a.sum));
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				scanf("%d",&a.g[i][j]);
				a.sum[a.g[i][j]]++;
			}
		}
		a.cur=a.g[0][0];
		a.block[a.g[0][0]].push_back(0);
		d=-1;
		ans=INF;
		for(limit=0;limit<1000;limit++){
			if(dfs(a))break;
		}
		printf("%d\n",ans);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章