1010-Tempter of the Bone

题目链接


http://acm.hdu.edu.cn/showproblem.php?pid=1010

Sample Input
4 4 5
S.X.
..X.
..XD
….
3 4 5
S.X.
..X.
…D
0 0 0

Sample Output
NO
YES


解题思想


/*
- dfs+奇偶性剪枝 - 奇偶性剪枝:假设起点为s,终点为e,并且起点到 - 终点的最短路径为dis = e-s, - 假设dis为偶数,那么给定一个步数t,t > - dis(t为从起点到终点可能的步数,必须大于等 - t,反证:如果小于t<dis,如果给的t比最短路径 - 还小,肯定走不到),其次t与dis应该同为奇数, - 或同为偶数(重点)考虑对角线上的两点,从 - 走到另一点必须经过偶数步,同行或同列必须经 - 奇数步。 
*/

代码


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 8;
char a[maxn][maxn];
int point[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int N,M,T;
int sx,sy,ex,ey;
int flag = 0;
void dfs(int x, int y, int cnt)
{
    if(x<1 || x>N || y<1 || y>M) //越界
        return;
    if(x==ex && y==ey && cnt == T) //满足条件
    {
        flag = 1;
    }
    if(flag)
        return;
    int shor = abs(ex-x)+abs(ey-y);
    int tem = T-cnt - shor ; //已走cnt步,剩余T-cnt步,shor为俩点最短距离
    if(tem < 0 || tem & 1) //奇偶性剪枝
        return;
    for(int i=0; i<4; ++i)
    {
        int dx = x + point[i][0];
        int dy = y + point[i][1];
        if(a[dx][dy]!='X')
        {
            a[dx][dy] = 'X';
            dfs(dx,dy,cnt+1);
            a[dx][dy] = '.'; //回溯
        }

    }

}
int main()
{
    while(scanf("%d%d%d",&N,&M,&T)!=EOF)
    {
        getchar(); //必须加,应为接收完nmt后,有个\n,需要接收掉,不然后占用数组空间
        if(!N && !M && !T)
            break;
        int wall = 0;
        for(int i=1; i<=N; ++i)
        {

            for(int j=1; j<=M; ++j)
            {
                scanf("%c",&a[i][j]);
                if(a[i][j] == 'S')
                {
                    sx = i;
                    sy = j;
                }
                if(a[i][j] == 'D')
                {
                    ex = i;
                    ey = j;
                }
                if(a[i][j] == 'X')
                {
                    wall++;
                }
            }
            getchar(); //与上面的同理
        }
        if(M*N-wall < T)
        {
            cout << "NO" <<endl;
            continue;
        }
        a[sx][sy] = 'X';
        flag = 0;
        dfs(sx,sy,0);
        if(flag)
        {
            cout << "YES" <<endl;
        }
        else
        {
            cout << "NO" <<endl;
        }
    }
    return 0;
}

全部评论

相关推荐

10-30 19:23
已编辑
山东大学(威海) C++
牛至超人:其实简历是不需要事无巨细的写的,让对方知道你有这段经历就行了,最重要的是面试的时候讲细讲明白
点赞 评论 收藏
分享
来,说点可能被同行“骂”的大实话。🙊当初接数字马力Offer时,朋友都说:“蚂蚁的“内包”公司?你想清楚啊!”但入职快一年后的今天,我反而对他有了不一样的看法!🔹&nbsp;是偏见?还是信息差!之前没入职之前外面都在说什么岗位低人一等这类。实际上:这种情况不可至否,不能保证每个团队都是其乐融融。但我在的部门以及我了解的周边同事都还是十分好相处的~和蚂蚁师兄师姐之间也经常开一些小玩笑。总之:身份是蚂蚁公司给的,地位是自己挣的(一个傲娇女孩的自述)。🔹&nbsp;待遇?玩的就是真实!试用期工资全额发!六点下班跑得快(早9晚6或者早10晚7,动态打卡),公积金顶格交。别听那些画饼的,到手的钱和下班的时间才是真的(都是牛马何必难为牛马)。🔹&nbsp;能不能学到技术?来了就“后悔”!我们拥有权限直通蚂蚁知识库,技术栈多到学不完。说“学不到东西”的人,来了可能后悔——后悔来晚了(哈哈哈哈,可以不学但是不能没有)!💥&nbsp;内推地址:https://app.mokahr.com/su/ueoyhg❗我的内推码:NTA6Nvs走我的内推,可以直达业务部门,面试流程更快速,进度可查!今天新放HC,之前挂过也能再战!秋招已经正式开始啦~机会就摆在这,敢不敢来试一试呢?(和我一样,做个勇敢的女孩)
下午吃泡馍:数字马力的薪资一般哇,5年经验的java/测试就给人一万出头,而且刚入职第三天就让人出差,而且是出半年
帮你内推|数字马力 校招
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务