• hdu 1175 连连看


    题目中需要注意的地方:

    1、转弯次数不能超过两次

    2、只有起点位置和终点位置的棋子相同的时候,才进行dfs搜索,否则直接输出"NO"。如果不这样做,会超时!

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 typedef struct Node
      6 {
      7     int x1, y1;
      8     int x2, y2;
      9 }Node;
     10 
     11 const int N = 1010;
     12 const int dir[4][2] = { {-1,0}, {0,1}, {1,0}, {0,-1} };
     13 Node inquire[50];    //保存询问信息
     14 bool visit[N][N];    //标记数组
     15 int board[N][N];     //棋盘
     16 int n, m, q;         //行、列、询问次数
     17 
     18 /* 输入(参数含义:行、列) */
     19 void input(void)
     20 {
     21     for (int i = 1; i <= n; ++i)
     22         for (int j = 1; j <= m; ++j)
     23             scanf("%d", &board[i][j]);
     24     scanf("%d", &q);
     25     for (int i = 0; i < q; ++i)
     26         scanf("%d %d %d %d", &inquire[i].x1, &inquire[i].y1, &inquire[i].x2, &inquire[i].y2);
     27 }
     28 
     29 /* 判断是否越界 */
     30 inline bool inBoard(const int &row, const int &col)
     31 {
     32     return 1 <= row && row <= n && 1 <= col && col <= m;
     33 }
     34 
     35 /* dfs搜索(参数含义:行、列、第几次询问、当前的方向、当前的转弯次数) */
     36 bool dfs(const int &row, const int &col, const int &index, int direction ,int turnCount)
     37 {
     38     if (-1 != direction && 0 < board[row][col])// "1 != direction"的目的是防止起点的棋子进来
     39     {
     40         if (inquire[index].x2 == row && inquire[index].y2 == col)
     41             return true;  //碰到一个棋子,棋子能匹配,找到答案
     42         else
     43             return false; //碰到一个棋子,但是这个棋子不能匹配,因此需要退回去,不能继续向下搜索
     44     }
     45 
     46     for (int i = 0; i < 4; ++i)
     47     {
     48         int r = row + dir[i][0];
     49         int c = col + dir[i][1];
     50         if (true == inBoard(r, c) && false == visit[r][c])
     51         {
     52             //记录之前的方向和转弯次数,用于后面回溯
     53             int lastDirection = direction;
     54             int lastTurnCount = turnCount;
     55 
     56             //处理转弯
     57             if (-1 == direction) //方向为-1表示刚开始搜索,还没有选方向
     58             {
     59                 direction = i;
     60             }
     61             else if ( i != direction)  //之前的方向与当前的方向不同,表示一次转弯
     62             {
     63                 if (turnCount + 1 > 2) //转弯次数不能超过两次
     64                     continue;
     65                 direction = i;
     66                 turnCount++;
     67             }
     68 
     69             visit[r][c] = true;
     70 
     71             //搜索
     72             if (true == dfs(r, c, index, direction, turnCount))
     73                 return true;
     74 
     75             //回溯
     76             visit[r][c] = false;
     77             direction = lastDirection;
     78             turnCount = lastTurnCount;
     79         }
     80     }
     81     return false;
     82 }
     83 
     84 int main(void)
     85 {
     86     while (scanf("%d %d", &n, &m), n || m)
     87     {
     88         input();
     89         for (int i = 0; i < q; ++i)
     90         {
     91             if (board[inquire[i].x1][inquire[i].y1] != board[inquire[i].x2][inquire[i].y2])
     92             {
     93                 printf("NO
    ");
     94                 continue;
     95             }
     96             memset(visit, 0, sizeof(visit)); //搜索成功了,就不会回溯visit,所以每次开始搜索的时候需要清空visit
     97             visit[inquire[i].x1][inquire[i].y1] = true;
     98             if (true == dfs(inquire[i].x1, inquire[i].y1, i, -1, 0))//-1代表没有方向
     99                 printf("YES
    ");
    100             else
    101                 printf("NO
    ");
    102         }
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    [CF1166E] The LCMs Must be Large
    AtCoder Beginner Contest 161
    [CF1168B] Good Triple
    [CF1172B] Nauuo and Circle
    [CF1185E] Polycarp and Snakes
    [CF1187E] Tree Painting
    Codeforces Round #631 (Div. 2)
    [CF1200E] Compress Words
    Thinkphp绕过宝塔getshell
    如何成为一个漏洞赏金猎人
  • 原文地址:https://www.cnblogs.com/yongqiang/p/5691406.html
Copyright © 2020-2023  润新知