• HDU 1175 连连看(BFS或DFS)


    连连看

                  Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

                           Total Submission(s): 12814    Accepted Submission(s): 3351

    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
     
     
     
    方法一:用BFS求解
      1 #include <stdio.h>
      2 #include <string.h>
      3 
      4 typedef struct _QUEUE           //定义一个队列,保存相关信息
      5 {
      6     int preX, preY;
      7     int curX, curY;
      8     int turnCount;
      9 }QUEUE;
     10 
     11 int M, N;                       //N代表行,M代表列
     12 int sRow, sCol;                 //起始点
     13 int eRow, eCol;                 //到达的终点
     14 const int MAX_NUM = 1005;
     15 int   maze[MAX_NUM][MAX_NUM];   //记录迷宫
     16 int   step[MAX_NUM][MAX_NUM];   //记录某个点的最小拐弯次数
     17 QUEUE qu[MAX_NUM * MAX_NUM];    //对每个符合条件的点入队列
     18 int   dir[4][2] = {{0,-1}, {0,1}, {-1,0}, {1,0}};
     19 
     20 bool bfs()
     21 {
     22     memset(step, 0x7f, sizeof(step)); //将每个点的最小拐弯次数初始为正无穷
     23     qu[0].preX = qu[0].curX = sRow;   //起点入队列
     24     qu[0].preY = qu[0].curY = sCol;
     25     qu[0].turnCount = 0;
     26 
     27     int front = -1, tail = 0;
     28     while(front < tail)              //队列不空时循环
     29     {
     30         QUEUE tempP = qu[++front];
     31         if(tempP.curX == eRow && tempP.curY == eCol) //找到出口
     32             return true;
     33 
     34         for(int k = 0; k < 4; k++)   //向四个方向拓展
     35         {
     36             QUEUE tempC;
     37             tempC.preX = tempP.curX; //计算下一个点的相关信息
     38             tempC.preY = tempP.curY;
     39             tempC.curX = tempP.curX + dir[k][0];
     40             tempC.curY = tempP.curY + dir[k][1];
     41 
     42             if(tempC.curX > 0 && tempC.curX <= N && tempC.curY > 0 
     43                 && tempC.curY <= M && maze[tempC.curX][tempC.curY] == 0)    
     44             {
     45                 if( (tempP.preX == tempP.curX && tempP.curX == tempC.curX)
     46                     || (tempP.preY == tempP.curY && tempP.curY == tempC.curY) )
     47                 {
     48                     tempC.turnCount = tempP.turnCount;    //在同一条直线
     49                 }
     50                 else
     51                 {
     52                     tempC.turnCount = tempP.turnCount + 1;//不在同一条直线
     53                 }
     54 
     55                    //若拐点小于等于2,且小于step[][],主要是防止将已经走过的点入队列
     56                 if(tempC.turnCount <= 2 && tempC.turnCount < step[tempC.curX][tempC.curY])
     57                 {
     58                     step[tempC.curX][tempC.curY] = tempC.turnCount;
     59                     qu[++tail] = tempC;                  //符合条件的点入队列
     60                 }
     61             }
     62         }
     63     }
     64     return false; //找不到出口,返回false
     65 }
     66 
     67 int main()
     68 {
     69     while(scanf("%d %d", &N, &M) && M+N)
     70     {
     71         for(int row = 1; row <= N; row++)
     72         {
     73             for(int col = 1; col <= M; col++)
     74             {
     75                 scanf("%d", &maze[row][col]);
     76             }
     77         }
     78 
     79         int Q;
     80         scanf("%d", &Q);
     81         while(Q--)
     82         {
     83             scanf("%d %d %d %d", &sRow, &sCol, &eRow, &eCol);
     84 
     85             if(maze[sRow][sCol] == 0 || maze[sRow][sCol] != maze[eRow][eCol]
     86                 || maze[eRow][eCol] == 0 || (sRow == eRow && sCol == eCol))
     87             {
     88                 printf("NO\n");
     89                 continue;
     90             }
     91 
     92             int tempValue = maze[eRow][eCol];//将终点值赋给临时变量
     93             maze[eRow][eCol] = 0;            //将终点位置置为0
     94 
     95             bool bResult = bfs();            //BFS搜索
     96 
     97             if(bResult)
     98                 printf("YES\n");
     99             else
    100                 printf("NO\n");
    101 
    102             maze[eRow][eCol] = tempValue;   //恢复终点位置的值
    103         }
    104     }
    105     return 0;
    106 }

    方法二:DFS求解

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 int M, N;                           //N代表行,M代表列
     5 int sRow, sCol;                     //起始点
     6 int eRow, eCol;                     //到达的终点
     7 const int MAX_NUM = 1005;
     8 int   maze[MAX_NUM][MAX_NUM];       //记录迷宫
     9 int   visit[MAX_NUM][MAX_NUM];      //记录某个点是否被访问
    10 int   dir[4][2] = {{0,-1}, {0,1}, {-1,0}, {1,0}};
    11 bool  bResult;                      //记录结果
    12 
    13 //分别记录前一个点位置,当前点的位置,以及当前点的拐弯次数
    14 void dfs(int preX, int preY, int curX, int curY, int turnCount)
    15 {
    16     if(bResult)return;               //已经找到方案则返回
    17     if(turnCount > 2)return;         //当前点的拐弯次数大于2,直接返回
    18 
    19     if(curX == eRow && curY == eCol) //找到终点,置bResult为true
    20     {
    21         bResult = true;
    22         return ;
    23     }
    24 
    25     for(int k = 0; k < 4; k++)       //向四个方向拓展
    26     {
    27         int nextX = curX + dir[k][0];
    28         int nextY = curY + dir[k][1];
    29 
    30         if(nextX > 0 && nextX <= N && nextY > 0 && nextY <= M) //在迷宫范围内
    31         {
    32             if(!visit[nextX][nextY] && maze[nextX][nextY] == 0)//没有访问且值为0
    33             {
    34                 int nTurn;
    35                 if( (preX==curX&&curX==nextX || preY==curY&&curY==nextY) )
    36                 {
    37                     nTurn = turnCount;       //若在一条线上,拐点数目不增加
    38                 }
    39                 else
    40                 { 
    41                     nTurn = turnCount + 1;   //不在同一条线上,拐点次数加一
    42                 }
    43                 
    44                 visit[nextX][nextY] = 1;     //标记为已访问
    45                 dfs(curX, curY, nextX, nextY, nTurn);  //搜索下一个点
    46                 visit[nextX][nextY] = 0;     //回溯时,恢复原来状态
    47             }
    48         }
    49     }
    50 }
    51 
    52 int main()
    53 {
    54     while(scanf("%d %d", &N, &M) && M+N)
    55     {
    56         for(int row = 1; row <= N; row++)
    57         {
    58             for(int col = 1; col <= M; col++)
    59             {
    60                 scanf("%d", &maze[row][col]);
    61             }
    62         }
    63 
    64         int Q;
    65         scanf("%d", &Q);
    66         while(Q--)
    67         {
    68             scanf("%d %d %d %d", &sRow, &sCol, &eRow, &eCol);
    69 
    70             if(maze[sRow][sCol] == 0 || maze[sRow][sCol] != maze[eRow][eCol] 
    71                 || maze[eRow][eCol] == 0 || (sRow == eRow && sCol == eCol))
    72             {
    73                 printf("NO\n");
    74                 continue;
    75             }
    76 
    77             bResult = false;
    78             memset(visit, 0, sizeof(visit));
    79 
    80             int tempValue = maze[eRow][eCol]; //将终点值赋给临时变量
    81             maze[eRow][eCol] = 0;             //将终点位置置为0
    82 
    83             dfs(sRow, sCol, sRow, sCol, 0);   //DFS搜索
    84 
    85             if(bResult)
    86                 printf("YES\n");
    87             else
    88                 printf("NO\n");
    89 
    90             maze[eRow][eCol] = tempValue;     //恢复终点位置的值
    91         }
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    iozone的三大神器之一fileop
    nginx反向代理配置相对路径
    自建yum源解决Ceph搭建过程中从官网取包慢的问题
    SourceInsight 4重启之后文件变只读无法编辑
    Android应用启动时Activity被创建两次
    mfscli的使用方法(解决mfscgi响应慢的问题)
    漫谈moosefs中cgi各项的意义
    Linux stress CPU的测试方法
    磁盘测试工具FIO工具安装和使用方法
    iperf测试工具
  • 原文地址:https://www.cnblogs.com/Dreamcaihao/p/3103304.html
Copyright © 2020-2023  润新知