• 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
    ");
     94                 continue;
     95             } 
     96             //如果查询的位置刚好相邻
     97             if(y1==y2&&(x1+1==x2||x1-1==x2))//左右相邻 
     98             {
     99                 printf("YES
    ");
    100                 continue;
    101             }
    102             if(x1==x2&&(y1+1==y2||y1-1==y2))//上下相邻 
    103             {
    104                 printf("YES
    ");
    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
    ");
    114             if(flag==0)
    115                 printf("NO
    ");
    116         }
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    PyCharm 3.4注册码
    监控Oracle索引是否被启用
    Oracle execute plan 原理分析与实例分享(转)
    6 个重构方法可帮你提升代码质量(转载)
    跟我一起学Oracle 11g【2】----用户管理(转载)
    notecore设置linux/Unix系统文件权限
    Unicode特殊字符的坑
    net多线程
    走过的HttpClient坑
    Postgre备份还原
  • 原文地址:https://www.cnblogs.com/greenaway07/p/10500694.html
Copyright © 2020-2023  润新知