POJ 2308 DFS+BFS

题目链接:http://poj.org/problem?id=2308

这题没什么坑,就是dfs+bfs,bfs搜索当前方块可以与哪个快消,dfs暴力枚举先消哪个对。

/*--------------------------------------------------------
                       Author:log                         
   Created Time:2016年04月15日 星期五 18时06分54秒
--------------------------------------------------------*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>

using namespace std;

const int maxn=12;

int grap[maxn][maxn];
int num[4];
struct Node{
	int x,y;
	Node(){}
	Node(int x,int y):x(x),y(y){}
}q[maxn*maxn];
int vis[maxn][maxn];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int n,m;

void bfs(int x,int y,Node *p,int &cot){
	memset(vis,-1,sizeof(vis));
	int l=0,r=0;
	cot=0;
	q[r++]=Node(x,y);
	vis[x][y]=0;
	int xt,yt;
	Node u;
	while(l<r){
		u=q[l++];
		if(vis[u.x][u.y]>=3)break;
//		printf("%d:%d %d\n",l,u.x,u.y);
		for(int i=0;i<4;i++){
			xt=u.x+dx[i];yt=u.y+dy[i];
			while(xt>=0&&xt<n&&yt>=0&&yt<m){
				if(grap[xt][yt]!=-1){
					if(vis[xt][yt]==-1){
						if(grap[xt][yt]==grap[x][y]){
							p[cot++]=Node(xt,yt);
							vis[xt][yt]=vis[u.x][u.y]+1;
//							printf("			add%d:%d %d\n",cot,p[cot-1].x,p[cot-1].y);
						}
					}
					break;
				}
				if(vis[xt][yt]!=-1){
					xt+=dx[i];yt+=dy[i];
					continue;
				}
//				printf("push:%d %d\n",xt,yt);
				q[r++]=Node(xt,yt);
				vis[xt][yt]=vis[u.x][u.y]+1;
				xt+=dx[i];yt+=dy[i];
			}
		}
	}
}

bool ok(){
	int cot=0;
	for(int i=0;i<4;i++){
		if(num[i]==2)cot++;
	}
	if(cot<=1)return true;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(grap[i][j]!=-1&&grap[i][j+1]!=-1){
				if(num[grap[i][j]]==2&&num[grap[i][j+1]]==2){
					if(grap[i][j]==grap[i+1][j+1]&&grap[i][j+1]==grap[i+1][j])return false;
				}
			}
		}
	}
	return true;
}

bool flag;
bool dfs(int cnt){
	if(cnt<=0)return flag=true;
	int tmp;
	Node p[40];
	int cot;
	if(!ok())return false;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(grap[i][j]!=-1){
				bfs(i,j,p,cot);
				tmp=grap[i][j];
				for(int k=0;k<cot;k++){
					num[tmp]-=2;
					grap[i][j]=grap[p[k].x][p[k].y]=-1;
					if(dfs(cnt-2))return flag=true;
					num[tmp]+=2;
					grap[i][j]=grap[p[k].x][p[k].y]=tmp;
				}
			}
		}
	}
	return flag=false;
}

int main(){
	char c;
	int cnt;
	bool judge;
	while(scanf("%d %d",&n,&m)==2&&(n||m)){
	memset(grap,-1,sizeof(grap));
	memset(num,0,sizeof(num));
	cnt=0;
		for(int i=0;i<n;i++){
			getchar();
			for(int j=0;j<m;j++){
				c=getchar();
				switch(c){
					case '*':grap[i][j]=-1;break;
					default:grap[i][j]=c-'A';num[c-'A']++;break;
				}
			}
		}
		flag=false;
		judge=true;
		for(int i=0;i<4;i++){
			if(num[i]%2)judge=false;
			cnt+=num[i];
		}
		if(!judge)printf("no\n");
		else {
			dfs(cnt);
			if(flag)printf("yes\n");
			else printf("no\n");
		}
	}
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值