题目链接: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;
}