[HDU1010] Tempter of the Bone

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

 

题目大意呢,就是一只doge要从S出发正好走T步到达终点D,注意不是T步之内(这不科学)求doge是否能够跑走

看上去就是一搜索题,这里我们讲三种方法

1. DFS+剪枝

DFS好不好打?好打!那就用DFS!

可是当你打完DFS提交上去发现了Time Limit Exceeded

看上去本题没什么剪枝的啊

其实是有的

既然狗要在正好T步走到D,那么,我们判断下S与D的曼哈顿距离p,再把这个p与T进行比较,如果奇偶性不同,就达不到

= =看上去很有道理?其实就很有道理。

这么剪枝,过了!

贴代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<cmath>
using namespace std;
int n,m,k;
char map[10][10];
bool vis[10][10];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
bool flag=0;
int endx,endy;
bool check(int x, int y) {
    if (x>=1 && x<=n && y>=1 && y<=m && !vis[x][y] && map[x][y]!='X') return true;
    return false;
}
void newer() {
   // memset(map,0,sizeof(map));
    memset(vis,0,sizeof(vis));
    flag=0;endx=0;endy=0;
}
void dfs(int step,int x,int y) {
    //if(flag) return;
    //if(step>k+1) return;
    if(step==k+1) {
        if(x==endx&&y==endy) flag=1;
        return;
    }
    for (int i=0;i<4;++i) {
        int xx=x+dx[i],yy=y+dy[i];
        if(check(xx,yy)) {
            vis[xx][yy]=1;
            dfs(step+1,xx,yy);
            if(flag) return;
            vis[xx][yy]=0;
        }
    }
}
int main() {
    while(~scanf("%d%d%d",&n,&m,&k)) {
        if(n==0&&m==0&&k==0) break;
        //printf("%d%d%d",n,m,k);
        newer();
        for (int i=1;i<=n;++i) {
            getchar();
            for(int j=1;j<=m;++j) scanf("%c",&map[i][j]);
        }
        int walls=0,startx,starty;
        for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) {
            if(map[i][j]=='X') walls++;
            if(map[i][j]=='S') {startx=i;starty=j;}
            if(map[i][j]=='D') {endx=i;endy=j;}
        }
        getchar();
        if(abs(startx-endx)+abs(starty-endy)>k||(starty+endy+startx+endx+k)%2==1) {
            printf("NO\n");
            continue;
        }

        if(n*m-walls<k) {printf("NO\n");continue;}
        vis[startx][starty]=1;
        dfs(1,startx,starty);
        if(flag) printf("YES\n"); else printf("NO\n");
    }
    return 0;
}
View Code

楼主的代码风格有点丑- -我得承认这点

2. BFS

dxy巨巨看到我DFS打跪了就鼓动我打BFS,可惜我懒,于是就想出来了上面那个剪枝。

话说肯定有人打BFS,BFS应该不会TLE的,读者有兴趣可自己尝试下。

3. DP

wyh巨巨看到dxy巨巨鼓动我打BFS,就来鼓动我打DP了

看上去确实能DP

f[k][x][y]表示第k步能否走到[x,y]

那么状态转移方程就很好列了,判断上下左右四次就结束了

看上去真的很有道理

但是因为楼主太懒,也懒得写了,于是就把DFS剪枝想出来了

好了吐槽完了,谢谢各位看官!

posted @ 2015-05-17 17:04  TonyFang  阅读(164)  评论(0编辑  收藏  举报