HDU 1175连连看

Problem 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 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
 

 

Author
lwg

 

 

题解:连连看~剪枝。题意明了。就是考虑的情况比较细。。。良心注释orz.开学浪了两周,连DFS长啥样都不知道了,看别人的题解挺费劲。

而且编译以及输入数据的时候程序崩溃了几次,全是因为输入的时候没有加&。。。哭了

 

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 int a[1005][1005];//输入的棋盘情况 
  7 int vis[1001][1001];//标记 
  8 int x1,y1,x2,y2;//两个棋子的坐标 
  9 int n,m;//棋盘的行数列数 
 10 int d,k;//方向,拐弯次数 
 11 int flag=0;//标记是否可以连连看 ,1为可以,0为不可以 
 12 void query(int x,int y,int d,int k)
 13 {
 14     if(flag)//找到并回溯 
 15         return;
 16     if(k>=3)//拐弯次数大于两次
 17         return;
 18     if(x<=0||y<=0||x>n||y>m) //越界 
 19         return;
 20     if(x==x2&&y==y2)//找到了
 21     {
 22         flag=1;//标记找到 
 23         return;
 24     }
 25     //转弯两次,如果目标点坐标与当前方向是否一致
 26     if(k==2)
 27     {
 28         if(!(d==1&&x>x2&&y==y2||d==2&&x<x2&&y==y2||d==3&&y>y2&&x==x2||d==4&&y<y2&&x==x2))//上下左右 
 29             return;
 30     }
 31     if(a[x][y]!=0)//当前路径上的格子上有别的棋子,此路不通。 
 32         return; 
 33     if(vis[x][y])
 34         return;
 35     vis[x][y]=1;
 36     //上下左右继续搜索 
 37      if(d==1)
 38      {
 39         query(x-1,y,1,k);//因为方向不变,所以k没有+1,同理其他的拐弯了就+1 
 40         query(x+1,y,2,k+1);
 41         query(x,y-1,3,k+1);
 42         query(x,y+1,4,k+1);
 43      } 
 44      if(d==2)
 45      {
 46          query(x-1,y,1,k+1);
 47         query(x+1,y,2,k);
 48         query(x,y-1,3,k+1);
 49         query(x,y+1,4,k+1);
 50      }
 51      if(d==3)
 52      {
 53          query(x-1,y,1,k+1);
 54         query(x+1,y,2,k+1);
 55         query(x,y-1,3,k);
 56         query(x,y+1,4,k+1);
 57      }
 58      if(d==4)
 59      {
 60          query(x-1,y,1,k+1);
 61         query(x+1,y,2,k+1);
 62         query(x,y-1,3,k+1);
 63         query(x,y+1,4,k);
 64      }
 65      vis[x][y]=0;//标记走过这个点(x,y)了 
 66 }    
 67 int main()
 68 {
 69     
 70     while(scanf("%d%d",&n,&m))
 71     {
 72         memset(a,0,sizeof(a));
 73         if(m==n&&m==0)
 74             break;
 75         
 76         for(int i=1;i<=n;i++)
 77         {
 78             for(int j=1;j<=m;j++)
 79             {
 80                 scanf("%d",&a[i][j]);
 81             }
 82         }
 83         int q;
 84         scanf("%d",&q);
 85         while(q--)
 86         {
 87             flag=0;
 88             memset(vis,0,sizeof(vis));
 89             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
 90             //位置上没有棋子、两个棋子不同、两个坐标相同 
 91             if((a[x1][y1]==0||a[x2][y2]==0)||a[x1][y1]!=a[x2][y2]||(x1==x2&&y1==y2))
 92             {
 93                 printf("NO\n");
 94                 continue;
 95             } 
 96             //如果查询的位置刚好相邻
 97             if(y1==y2&&(x1+1==x2||x1-1==x2))//左右相邻 
 98             {
 99                 printf("YES\n");
100                 continue;
101             }
102             if(x1==x2&&(y1+1==y2||y1-1==y2))//上下相邻 
103             {
104                 printf("YES\n");
105                 continue;
106             } 
107             //如果查询的位置不相邻,看看能不能转两次就连上 
108             query(x1-1,y1,1,0);
109             query(x1+1,y1,2,0);
110             query(x1,y1-1,3,0);
111             query(x1,y1+1,4,0);
112             if(flag==1)
113                 printf("YES\n");
114             if(flag==0)
115                 printf("NO\n");
116         }
117     }
118     return 0;
119 }

 

posted @ 2019-03-09 14:33  鹤花之歌  阅读(126)  评论(0编辑  收藏  举报