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

本来以为是水题,居然TEL。。。 ┭┮﹏┭┮ // 不过还好过了
https://vjudge.net/problem/HDU-1010#author=boboyang

同样是走迷宫,不过有意思的是,它不让你找最短路,而是问能否恰好的在第T分钟逃出(抵达door位置)
哎呦嘿放弃bfs果断dfs难不倒我 ——>> 然后就一直TEL》。。。需要剪枝!!!

1.搜索过程中只要答案确定立刻跳出并输出
2.时间已到T仍未抵达door,直接返回假
3.' ``奇偶数剪枝``由题:最短路和T奇偶性必相同
4.若 T > min_dist(最短距离) 直接 "NO"
Ⅲ 可以理解为: 偏离最短路径 s 再回到最短路上需再走 s (证明略)
代码:(有些工具函数可自行忽略)
// Times: 350ms
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include<iomanip>
using namespace std;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
const int maxn = 1e9;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int dx[] = {0, 0,1,-1};
const int dy[] = {1,-1,0, 0};
struct P {
    int x, y;
    P(int x = 0, int y = 0): x(x), y(y) {}
};
int r, c, T;
int ur, uc, dr, dc;
char s[10][10];
int d[10][10];

inline bool in_border (int mx, int my) {
    return mx>=0 && mx<r && my>=0 && my<c;
}
bool cmp (const void* p1, const void* p2) {
    return true;
}

int dfs(int x, int y, int mins) {
    if(mins == T) {
        if(x == dr && y == dc) return 1;
        return 0;//第二处
    }

    for(int i = 0; i < 4; i++) {
        int mx = x + dx[i], my = y + dy[i];
        if(in_border(mx, my) && !d[mx][my] && s[mx][my] != 'X') {

            d[mx][my] = 1;
            if(dfs(mx, my, mins+1)) return 1;//第一处
            d[mx][my] = 0;
        }
    }
    return 0;
}
int main() {//int T; cin >> T;

    while(cin >> r >> c >> T && r)  {
        for(int i = 0; i < r; i++) {
            scanf("%s", s[i]);
            for(int j = 0; j < c; j++) {
                if(s[i][j] == 'S') ur = i, uc = j;
                if(s[i][j] == 'D') dr = i, dc = j;
            }
        }
        int min_dist = (abs(ur-dr)+abs(uc-dc));
        if(min_dist%2 != T%2 || T < min_dist)//第三四处
            cout << "NO" << endl;
        else {
            memset(d, 0, sizeof(d));
            d[ur][uc] = 1;
            int flag = 0;
            for(int i = 0; i < 4; i++) {
                int mx = ur + dx[i], my = uc + dy[i];
                if(in_border(mx, my) && s[mx][my] != 'X') {
                    d[mx][my] = 1;
                    if(dfs(mx, my, 1)) {
                        flag = 1; break;
                    }
                    d[mx][my] = 0;
                }
            }
            cout << (flag ? "YES": "NO") << endl;
        }
    }
    return 0;
}

好像早日开学= =…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值