连连看

HDU - 1175

“连连看”相信很多人都玩过。没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的。现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过。 
玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。 

Input输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000),分别表示棋盘的行数与列数。在接下来的n行中,每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子,正整数表示棋子的类型。接下来的一行是一个正整数q(0<q<50),表示下面有q次询问。在接下来的q行里,每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时,输入结束。 
注意:询问之间无先后关系,都是针对当前状态的! 
Output每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。 
Sample Input

3 4
1 2 3 4
0 0 0 0
4 3 2 1
4
1 1 3 4
1 1 2 4
1 1 3 3
2 1 2 4
3 4
0 1 4 3
0 2 4 1
0 0 0 0
2
1 1 2 4
1 3 2 3
0 0

Sample Output

YES
NO
NO
NO
NO
YES
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,map[][],x2,y2;
int e[][]={{-,},{,},{,-},{,}};
bool flag,vis[][];
bool ok(int x,int y){
if(x>=&&x<=n&&y>=&&y<=m&&map[x][y]==&&!vis[x][y])return ;
return ;
}
void dfs(int x,int y,int cnt,int pre){
if(cnt>=)return;
if(flag)return;
if(x==x2&&y==y2){flag=;return;}
if(!ok(x,y))return;
if(cnt==) {
if(!((pre==&&y2==y&&x2<x)||(pre==&&y2==y&&x2>x)||(pre==&&y2<y&&x2==x)||(pre==&&y2>y&&x2==x)))
return;
}
vis[x][y]=;
for(int i=;i<;i++){
int xx=x+e[i][],yy=y+e[i][];
if(i==pre)dfs(xx,yy,cnt,pre);
else dfs(xx,yy,cnt+,i);
}
vis[x][y]=;
}
int main(){
while(){
scanf("%d%d",&n,&m);
if(n==&&m==)return ;
for(int i=;i<=n;i++)for(int j=;j<=m;j++)scanf("%d",&map[i][j]);
int q;scanf("%d",&q);
int x1,y1;
while(q--){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if((x1==x2&&y1==y2)||map[x1][y1]!=map[x2][y2]||map[x1][y1]==||map[x2][y2]==){
printf("NO\n");continue;
}
flag=;
memset(vis,,sizeof(vis));
vis[x1][y1]=;
for(int i=;i<;i++){
int xx=x1+e[i][],yy=y1+e[i][];
dfs(xx,yy,,i);
}
if(flag){printf("YES\n");continue;}
else printf("NO\n");
}
}
}

dfs+剪枝

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m,map[][],x2,y2;
int e[][]={{-,},{,},{,-},{,}};
int visited[][];
struct node{
int x,y,d,cnt;
}cur,nxt;
queue<node>q;
bool ok(int x,int y){
if(x>=&&x<=n&&y>=&&y<=m&&map[x][y]==)return ;
return ;
}
void bfs(){
while(!q.empty()){
cur=q.front();q.pop();
int x=cur.x,y=cur.y;
if(x==x2&&y==y2){printf("YES\n");return;}
for(int i=;i<;i++){
nxt.x=cur.x+e[i][];
nxt.y=cur.y+e[i][];
nxt.d=i;nxt.cnt=cur.cnt;
if(nxt.d!=cur.d&&cur.d!=-)nxt.cnt++;
if(nxt.x<||nxt.x>n||nxt.y<||nxt.y>m||nxt.cnt>)continue;
if(nxt.x==x2&&nxt.y==y2){
printf("YES\n");
return;
}
if(map[nxt.x][nxt.y])continue;
if(nxt.cnt<visited[nxt.x][nxt.y]){
visited[nxt.x][nxt.y]=nxt.cnt;
q.push(nxt);
}
}
}
printf("NO\n");
}
int main(){
freopen("Soda.txt","r",stdin);
while(){
scanf("%d%d",&n,&m);
if(n==&&m==)return ;
for(int i=;i<=n;i++)for(int j=;j<=m;j++)scanf("%d",&map[i][j]);
int qu;scanf("%d",&qu);
int x1,y1;
while(qu--){
while(!q.empty())q.pop();
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1==x2&&y1==y2){
printf("NO\n");continue;
}
if(!map[x1][y1]||!map[x2][y2]||(map[x1][y1]!=map[x2][y2])){
printf("NO\n");continue;
}
cur.x=x1,cur.y=y1,cur.d=-,cur.cnt=;
q.push(cur);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
visited[i][j]=0x7fffffff;
bfs();
}
}
return ;
}

bfs不知道哪里写错了啊啊啊

05-12 22:10