• HDU-1010 Tempter of the Bone (DFS+奇偶剪枝)


    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1010


    思路:
    题目思路很清晰,一眼能看出用DFS来做,难点在于如果不剪枝就会超时。
    这题对我来说最大的收获就是了解了奇偶剪枝。


    奇偶剪枝理解:
    在一个矩阵中,设起点为(a, b),终点为(c, d)。则最短路min为abs(a-c)+abs(b-d),
    画图总结规律可以得出任意一条路径x,x-min必定为偶数。
    我自己对这种思想抽象理解为,若有1步不走在最短路上,则必定还需要1步走回最短路,因此必定多出2步。


    下面贴出AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 int n, m, t, flag = 0, vis[10][10];
     8 char maze[10][10];
     9 
    10 void dfs(int i, int j, int cur){
    11     if (flag||cur > t) return;
    12     if (maze[i][j] == 'X'||maze[i][j] == '#') return;
    13     if (cur < t&&maze[i][j] == 'D') return;
    14     if (cur == t&&maze[i][j] == 'D'){
    15         flag = 1;
    16         return;
    17     }
    18     else{
    19         if (!vis[i][j]){
    20         vis[i][j] = 1;
    21         dfs(i+1, j, cur+1);
    22         dfs(i-1, j, cur+1);
    23         dfs(i, j+1, cur+1);
    24         dfs(i, j-1, cur+1);
    25         vis[i][j] = 0;
    26         }
    27     }
    28 }
    29 
    30 int main()
    31 {
    32     //freopen("E://input.txt", "r", stdin);
    33     while(cin>>n>>m>>t){
    34         if(!n&&!m&&!t) break;
    35         for (int i = 0; i < 10; i++)
    36             for (int j = 0; j < 10; j++)
    37                 maze[i][j] = '#';
    38         int sx, sy, dx, dy, cnt = 0;
    39         for (int i = 1; i <= n; i++)
    40             for (int j = 1; j <= m; j++){
    41                 cin>>maze[i][j];
    42                 if (maze[i][j] == 'S'){
    43                     sx = i;
    44                     sy = j;
    45                 }
    46                 if (maze[i][j] == 'D'){
    47                     dx = i;
    48                     dy = j;
    49                 }
    50                 if (maze[i][j] == 'X') cnt++;
    51             }
    52         /*可走步数小于t必然不行*/
    53         if (m*n - cnt < t){
    54             cout<<"NO"<<endl;
    55             continue;
    56         }
    57         /*奇偶剪枝*/
    58         int minsum = abs(sx-dx)+abs(sy-dy);
    59         if ((t - minsum)%2 != 0){
    60             cout<<"NO"<<endl;
    61             continue;
    62         }
    63         dfs(sx, sy, 0);
    64         if (flag) cout<<"YES"<<endl;
    65         else cout<<"NO"<<endl;
    66         flag = 0;
    67         memset(maze, 0, sizeof(maze));
    68         memset(vis, 0, sizeof(vis));
    69     }
    70 
    71     return 0;
    72 }
  • 相关阅读:
    GDI+ 实现透明水印和文字
    delphi 7.0 DateTimePicker控件相同日期比较的问题
    LISTVIEW显示JPEG缩略图
    Delphi在Listview中加入Eeit控件
    LISTVIEW导出到EXCEL的通用函数
    在DateTimePicker上显示星期几
    用hook实现dll注入详解
    Delphi 动态选择控件的输入法
    Delphi FastReport动态加载图片
    项目中必须知道有关css和html的常识
  • 原文地址:https://www.cnblogs.com/robin1998/p/6359140.html
Copyright © 2020-2023  润新知