您的位置:首页 > 其它

HDU 1175 连连看(bfs+dfs 水过)

2017-04-29 16:29 453 查看

连连看

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 34879    Accepted Submission(s): 8673Problem Description“连连看”相信很多人都玩过。没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的。现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过。玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。 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 41 2 3 40 0 0 04 3 2 141 1 3 41 1 2 41 1 3 32 1 2 43 40 1 4 30 2 4 10 0 0 021 1 2 41 3 2 30 0 Sample Output
YESNONONONOYES一开始真的当成了连连看,后来错了几次重新看题发现是只针对当前状态的。。。代码压线过啊,耗时太长,以后再来慢慢剪枝吧....
代码:DFS:#include<stdio.h>#include<string.h>int n,m;int Ex,Ey;bool flag;char map[1050][1050];bool vis[1050][1050];int v[4][2]={-1,0,1,0,0,-1,0,1};int getDir(int x,int y){if(x==-1) return 1;//上if(x==1) return 2; //下if(y==-1) return 3; //左if(y==1) return 4;//右}void dfs(int x,int y,int dir,int count){//	printf("x=%d y=%d dir=%d count=%d\n",x,y,dir,count);if(flag) return ;if(count>2) return ;if(x==Ex&&y==Ey){flag=true;return ;}for(int i=0;i<4;i++){int xx=x+v[i][0];int yy=y+v[i][1];int temp=getDir(v[i][0],v[i][1]);int num=count;int vec=dir;if(dir+temp==3||dir+temp==7) continue ;//方向相反if(xx<=0||xx>n||yy<=0||yy>m||vis[xx][yy]||map[xx][yy]!='0') continue ;//边界条件if(temp!=dir){num++;vec=temp;}vis[xx][yy]=true;dfs(xx,yy,vec,num);vis[xx][yy]=false;}}int main(){int t;while(scanf("%d%d",&n,&m)&&n&&m){getchar();for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%c",&map[i][j]);getchar();}}scanf("%d",&t);int a,b,c,d;while(t--){scanf("%d %d %d %d",&a,&b,&c,&d);Ex=c;Ey=d;if((a==c&&b==d)||map[a][b]!=map[c][d]||map[a][b]=='0'||map[c][d]=='0')//起点终点不相等,或起点终点为同一位置,或为0{printf("NO\n");continue ;}memset(vis,false,sizeof(vis));char ch=map[c][d];map[c][d]='0';//终点设为可到达区域flag=false;dfs(a,b,0,-1);if(flag)printf("YES\n");elseprintf("NO\n");map[c][d]=ch;}}}BFS:#include<stdio.h>#include<queue>#include<string.h>using namespace std;struct Node{int x,y;int dir;int count;Node(){}Node(int _x,int _y,int _dir,int _count){x=_x;y=_y;dir=_dir;count=_count;}};int m,n;int Ex,Ey;int maxx;char map[1050][1050];bool vis[1050][1050];int v[4][2]={-1,0,1,0,0,-1,0,1};int getDir(int x,int y){if(x==-1) return 1;//上if(x==1) return 2; //下if(y==-1) return 3; //左if(y==1) return 4;//右}void printMap(){printf("********map*********\n");for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){printf("%c ",map[i][j]);}printf("\n");}printf("*******\n");}bool bfs(int a,int b){queue<Node> q;//push四个方向q.push(Node(a,b,1,0));q.push(Node(a,b,2,0));q.push(Node(a,b,3,0));q.push(Node(a,b,4,0));maxx=0;while(!q.empty()){if(q.size()>maxx) maxx=q.size();Node node=q.front();q.pop();int x=node.x;int y=node.y;//	 	printf("x==%d y==%d dir==%d count==%d  map=%c\n",x,y,node.dir,node.count,map[x][y]);if(x==Ex&&y==Ey)//终点{return true;}vis[x][y]=true;//标记当前位置for(int i=0;i<4;i++){Node node2=node;int xx=x+v[i][0];int yy=y+v[i][1];int temp=getDir(v[i][0],v[i][1]);//方向值if(temp+node.dir==3||temp+node.dir==7) continue ;//相反方向if(xx<=0||xx>n||yy<=0||yy>m||vis[xx][yy]) continue ;//边界条件if(temp!=node.dir)//转向,计数{node2.count=node.count+1;node2.dir=temp;}if(node2.count>2) continue ;//转折次数过多if(xx==Ex&&yy==Ey) return true;if(map[xx][yy]!='0') continue ;node2.x=xx;node2.y=yy;//		    printf("temp==%d dir==%d\n",temp,node.dir);q.push(node2);}}return false;}int main(){int t;while(scanf("%d%d",&n,&m)&&m&&n){getchar();memset(map,0,sizeof(map));for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%c",&map[i][j]);getchar();}}scanf("%d",&t);int a,b,c,d;while(t--){memset(vis,false,sizeof(vis));scanf("%d %d %d %d",&a,&b,&c,&d);Ex=c;Ey=d;if((a==c&&b==d)||map[a][b]!=map[c][d]||map[a][b]=='0'||map[c][d]=='0')//起点终点不相等,或起点终点为同一位置,或为0{printf("NO\n");continue ;}bool flag=bfs(a,b);if(flag){printf("YES\n");//	       	  map[a][b]='0';//			  map[c][d]='0';}elseprintf("NO\n");//	        printf("q.size==%d\n",maxx);//	        printMap();}}}/*8 81 2 7 0 0 3 5 60 0 4 0 5 6 0 00 0 5 0 4 8 7 00 0 0 0 0 0 0 02 0 8 0 0 0 0 76 5 3 0 2 4 0 97 0 0 0 0 0 0 79 7 9 8 6 6 1 51001 1 8 71 2 5 13 6 5 33 6 8 45 8 7 8*/

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: