题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2308
题意:就不说了。。
思路:dfs搜索消除路径,消除路径用bfs求。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#define maxn 100
using namespace std;
struct P
{
int x;
int y;
char c;
int num;
} node[maxn * maxn];
int x[] = {1, 0, -1, 0};
int y[] = {0, 1, 0, -1};
char Map[maxn][maxn];
bool vis[maxn][maxn];
bool book[maxn * maxn];
bool check[maxn][maxn];
int pos[maxn][maxn];
int num[4];
int n, m, sum;
bool Flag = 0;
bool isOK()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (Map[i][j] != '*' && Map[i][j+1] != '*' && num[Map[i][j] - 'A'] == num[Map[i][j+1] - 'A'] && num[Map[i][j] - 'A'] ==2)
{
if (Map[i][j] == Map[i+1][j+1] && Map[i][j+1] == Map[i+1][j])
return true;
}
}
}
return false;
}
bool C(int x, int y)
{
if(x < 0 || x > n + 1 || y < 0 || y > m + 1 || vis[x][y])
return 0;
return 1;
}
void BFS(P node)
{
memset(vis, 0, sizeof(vis));
memset(check, 0, sizeof(check));
queue<P> Q;
node.num = -1;
vis[node.x][node.y] = 1;
Q.push(node);
while(!Q.empty())
{
P pre = Q.front();
Q.pop();
if(pre.c == node.c && pre.num < 3)
{
int x = pos[node.x][node.y];
int y = pos[pre.x][pre.y];
if(x != y)
{
check[x][y] = 1;
continue;
}
}
for(int i = 0; i < 4; i++)
{
int xx = pre.x + x[i];
int yy = pre.y + y[i];
while(C(xx, yy))
{
if(Map[xx][yy] != '*' && Map[xx][yy] != node.c)
break;
P cur;
cur.x = xx;
cur.y = yy;
cur.c = Map[xx][yy];
cur.num = pre.num + 1;
Q.push(cur);
vis[xx][yy] = 1;
if(Map[xx][yy] != '*')
break;
xx += x[i];
yy += y[i];
}
}
}
}
void DFS(int cnt)
{
if(Flag)
return ;
if(isOK())
return ;
if(!cnt)
{
Flag = 1;
return ;
}
for(int i = 0; i < sum; i++)
{
if(book[i])
continue;
BFS(node[i]);
int x = node[i].x;
int y = node[i].y;
for(int j = 0; j < sum; j++)
{
if(j == i || book[j])
continue;
if(check[i][j])
{
int xx = node[j].x;
int yy = node[j].y;
Map[xx][yy] = Map[x][y] = '*';
book[i] = 1;
book[j] = 1;
DFS(cnt - 2);
Map[xx][yy] = Map[x][y] = node[i].c;
book[i] = 0;
book[j] = 0;
}
}
}
return ;
}
int main()
{
while(scanf("%d %d", &n, &m))
{
if(!n || !m)
break;
for(int i = 0; i < maxn; i++)
{
for(int j = 0; j < maxn; j++)
{
Map[i][j] = '*';
}
}
sum = 0;
memset(num, 0, sizeof(num));
for(int i = 1; i <= n; i++)
{
scanf("%s", Map[i] + 1);
for(int j = 1; j <= m; j++)
{
if(Map[i][j] != '*')
{
num[Map[i][j] - 'A']++;
node[sum].x = i;
node[sum].y = j;
node[sum].c = Map[i][j];
pos[i][j] = sum++;
}
}
}
bool flag = 1;
int tmp = 0;
for(int i = 0; i < 4; i++)
{
tmp += num[i];
if(num[i] & 1)
{
flag = 0;
}
}
if(!flag)
{
cout << "no" << endl;
}
else
{
Flag = 0;
memset(book, 0, sizeof(book));
DFS(tmp);
if(!Flag)
{
cout << "no" << endl;
}
else
{
cout << "yes" << endl;
}
}
}
return 0;
}