Dearboy is a game lover. Recently, he loves playing the game Lian Lian Kan. This game is played on a board with N*M grids, and lots of cards are put on the board in the grids. You should find a pair of the same cards, if not more than three segments can link this pair without passing any other cards, you can take this pair away from the board. (You may be puzzled about the meaning of not more than 3 segments, just refer to the figure below, in which we express some allowable links). Continue the process above, if you can clear all the cards, you win the game, otherwise you lose it.

If you have played this game, you may know that sometimes the game has no solution and you are sure to lose. Dearboy is very boring about the games without solutions, so he asks you, a famous programmer, to tell him whether he can win the giving game phase or not.

Input

The input consists of multiple test cases. The first line of each test case contains two integers N and M (2 <= N, M <= 10), which denote the sizes of the game board. The next N lines give the board layout, with each line containing M characters. A character is one of the following: ‘*’ (an empty position), ‘A’, ‘B’, ‘C’, ’D’ (the cards, which imply that there are at most 4 different kinds of cards). Different letters represent different cards. The number of same cards may be odd, and there may be more than one pair of the same cards.

The input is terminated with two 0’s. This test case shoud not be processed.

Output

For each test case, print in one line “yes” if Dearboy can win the game, “no” otherwise.

Sample Input

6 8
********
*A**C***
**B*****
***B*D**
****D***
********
2 2
AB
BA
6 8
***A****
*A**C***
**B***C*
***B*D**
****D***
********
0 0

Sample Output

no
no
yes

题意:

  • 连连看,但是转弯次数小于等于三次,而且外面一圈是封闭的。

题解:

  • 先用dfs进行递归,枚举每个状态,在进入每个状态时,需要用bfs得到有几个能到达的点,并进行消除。
  • 关键点在于回溯,也就是正确地理解回溯,在一个状态完成之后要将信息还原。
  • 剪枝:图中有输入B的子块则立即回溯。

//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;
#define P(a,b,c) make_pair(a,make_pair(b,c))
#define rep(i,a,n) for (int i=a;i<=n;i++) #define per(i,a,n) for (int i=n;i>=a;i–)
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef pair >pii;
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1000000007;
const int INF = 0x3f3f3f3f;
ll gcd(ll a, ll b) {
return b ? gcd(b, a%b) : a;
}
templateinline void gmax(T &A, T B){
(AA)A=B;
}
templateinline void gmin(T &A, T B){
(A>B)&&(A=B);//if(B
inline bool scan_d(T &ret) {
char c;
int sgn;
if(c=getchar(),c==EOF) return 0; //EOF
while(c!=’?’&&(c<'0'||c>‘9’)) c=getchar();
sgn=(c==’?’)?-1:1;
ret=(c==’?’)?0:(c-‘0’);
while(c=getchar(),c>=’0’&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1; } inline void outt(int x) { if(x>9) outt(x/10);
putchar(x%10+’0′);
}
const int MAXN = 1e6+10;
int m,n,flag;
int g[20][20];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int num[4],sum;

bool ojbk(){
rep(i,1,n-1){
rep(j,1,m-1){
if(g[i][j]==-1||g[i+1][j]==-1)continue;
if(g[i][j]==g[i+1][j+1]&&g[i][j+1]!=-1&&g[i][j+1]==g[i+1][j]&&num[g[i][j]]==2&&num[g[i][j+1]]==2)return true;
}
}
return false;
}
int s[40][10];
bool vis[20][20];
int NN;
struct node{
int x;
int y;
int cnt;
int last;
node(int _x=0,int _y=0,int _cnt=0,int _last=0):x(_x),y(_y),cnt(_cnt),last(_last){}
};
queueq;
void bfs(int X,int Y){
NN=0;
CLR(vis);
int v=g[X][Y];
vis[X][Y]=1;
while(!q.empty())q.pop();
q.push(node(X,Y,0,-1));
while(!q.empty()){
node tmp=q.front();q.pop();
int x=tmp.x,y=tmp.y,last=tmp.last,cnt=tmp.cnt;
rep(i,0,3){
int xx=x+dir[i][0],yy=y+dir[i][1],ccnt=cnt;
if(xx<=n&&xx>=1&&yy<=m&&yy>=1&&!vis[xx][yy]){
//可以加一个不等于上一个操作的continue,但是没有必要
if(g[xx][yy]!=v&&g[xx][yy]!=-1)continue;
if(g[xx][yy]==v){
s[NN][0]=xx;
s[NN++][1]=yy;
}
if(last!=i&&last!=-1)ccnt++;
if(ccnt<=2){ vis[xx][yy]=1; last=i; q.push(node(xx,yy,ccnt,last)); } } } } } void dfs(int cnt){ if(flag)return ; if(cnt==sum){ flag=true; return ; } if(ojbk())return ; rep(i,1,n){ rep(j,1,m){ if(flag)return; if (g[i][j]!=-1) { int v=g[i][j]; bfs(i,j); num[v]-=2; g[i][j]=-1; for (int k=0;k

发表评论

邮箱地址不会被公开。 必填项已用*标注