• zoj 2110 Tempter of the Bone ——DFS+剪枝


    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1110

    题意:

      给一个矩阵,‘X’代表墙壁,‘.’代表空格,‘S’代表起始位置,‘D’代表终点。从起点开始,每个空格只许经过一次,求在规定的时间t的时候,能否正好到达终点。每走一个花费1个单位时间。输入n,m,t,分别代表矩阵的行,列,规定的时间。

    思路:

      深度优先搜索,从起点开始,按照四个方向搜索,判断某个方向的下一个方格如果不是墙壁的话,就把它标为墙壁,然后从这个点继续往下搜索,如果从这个点往下搜索失败后,就要把这个点标记回原来的空格符号:‘.’。然后尝试下一个方向。直到i == di, j == dj, t == T的时候,表示搜索成功,flag = true; return; 其中si sj 是起点位置,di dj是终点位置,T是当前所花费的时间。

      然后还有几处剪枝:如果这个矩阵的空格的数目小于等于时间t,那么不可能成功。这在主函数里面可以剪枝。在dfs的过程中,如果发现剩余的时间小于当前位置到终点的最小距离,可以直接判断搜索失败;如果剩余的时间和当前位置到终点的最小时间的差值是奇数的话,可以判断搜索一定失败,可以剪枝,如果是偶数的话,则可能成功。

      今天突然发现,以前写的解题报告太搓了……向kedebug的博客学习,O(∩_∩)O哈哈~加油

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <cmath>
     9 #include <algorithm>
    10 #define lson l, m, rt<<1
    11 #define rson m+1, r, rt<<1|1
    12 using namespace std;
    13 typedef long long int LL;
    14 const int MAXN =  0x3f3f3f3f;
    15 const int  MIN =  -0x3f3f3f3f;
    16 const double eps = 1e-9;
    17 
    18 bool flag;
    19 char s[9][9];
    20 int t, n, m, si, sj, di, dj;
    21 int dir[4][4] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
    22 void dfs(int i, int j, int T){
    23   if (i == di && j == dj && T == t){
    24     flag = true; return;
    25   }
    26   if (i <= 0 || j <= 0 || i > n || j > m) return;
    27   int temp = t - T - abs(i-di) - abs(j-dj);
    28   if (temp < 0 || temp&1)return;
    29   for (int k = 0; k < 4; ++k){
    30     if (s[i+dir[k][0]][j+dir[k][1]] != 'X'){
    31       s[i+dir[k][0]][j+dir[k][1]] = 'X';
    32       dfs(i+dir[k][0], j+dir[k][1], T+1);
    33       if (flag) return;
    34       s[i+dir[k][0]][j+dir[k][1]] = '.';
    35     }
    36   }
    37   return;
    38 }
    39 int main(void){
    40 #ifndef ONLINE_JUDGE
    41   freopen("zoj2110.in", "r", stdin);
    42 #endif
    43   while (~scanf("%d%d%d", &n, &m, &t) && m+n+t){
    44     getchar();
    45     int wall = 0;
    46     for (int i = 1; i <= n; ++i){
    47       for (int j = 1; j <= m; ++j){
    48         scanf("%c", &s[i][j]);
    49         if (s[i][j] == 'S'){
    50           si = i; sj = j;
    51         }
    52         else if (s[i][j] == 'D'){
    53           di = i; dj = j;
    54         }
    55         else if (s[i][j] == 'X') wall++;
    56       }
    57       getchar();
    58     }
    59     if (m * n - wall <= t){
    60       printf("NO\n"); continue;
    61     }
    62     flag = false;
    63     s[si][sj] = 'X';
    64     dfs(si, sj, 0);
    65     if (flag) printf("YES\n");
    66     else printf("NO\n");
    67   }
    68 
    69   return 0;
    70 }

    开始敲的有错误,怎么也找不出来,然后急了,重新写了一遍,对了……代码能力,准确度有木有!!

    还有一点,就是这种读字符的题目,并且是一个一个字符读的,每行要用一个getchar()吸收换行符。并且读字符之前也要用一个getchar()吸收之前读数字的换行符,这个地方特别容易出错。

  • 相关阅读:
    mojoPortal学习笔记之页面访问权限控制
    页面中添加某模块
    styletreeview.css页面菜单
    mojoPortalprovider模式学习之1.1之IndexBuilderManager
    mojoportal学习笔记之HtmlContent模块
    CLR via c#学习笔记 之 引用类型与值类型
    mojoportal中解决下载文件名乱码问题
    mojoportal学习笔记之显示所有菜单
    blogmodule.css博客栏目
    [转]数据访问组件SqlHelper
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3003192.html
Copyright © 2020-2023  润新知