hdu1010题解

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

先枚举总步数,即开门周期的倍数,T,2*T,3*T,....iT<=总的可走方块数

如下代码:

for(int i = T;i<=block;i+=T){if(ok){break;}else dfs(st,0,i);}
然后进入dfs后各种剪枝:

if(ok)return;
if(u == en && num == iT){ok = 1;return;}///到达
if(num > iT)return;
int x = u/Nc,y = u%Nc;
if(abs(x-ex) + abs(y-ey)>iT-num)return;
if((iT - num - abs(x-ex) - abs(y-ey))%2)return;

各种剪枝:

已找到了一条路剪枝,当前步数超过总步数,剪枝

奇偶剪枝

已走步数+剩余最短路步数>iT剪枝

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int N = 30;
int Nr,Nc,T,block;
int st,en;
int ex,ey;
int ok;
int maps[N][N];
int vis[N][N];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
void dfs(int u,int num,int iT)
{
    if(ok)return;
    if(u == en && num == iT){ok = 1;return;}///到达
    if(num > iT)return;
    int x = u/Nc,y = u%Nc;
    if(abs(x-ex) + abs(y-ey)>iT-num)return;
    if((iT - num - abs(x-ex) - abs(y-ey))%2)return;
    for(int i = 0;i<4;i++){
        int newx = x + dir[i][0];
        int newy = y + dir[i][1];
        if(newx>=0 && newx<Nr && newy>=0 && newy <Nc && !maps[newx][newy] && !vis[newx][newy]){
            int newu = newx*Nc + newy;
            vis[newx][newy] = 1;
            dfs(newu,num+1,iT);
            vis[newx][newy] = 0;
        }
    }
}
int main()
{
    char s[N];
    char a;
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d%d",&Nr,&Nc,&T) == 3){
            a = getchar();
            if(Nc == 0 && Nr == 0 && T == 0)break;
            memset(vis,0,sizeof(vis));
            ok = 0,block = 2;
        for(int i = 0;i<Nr;i++){
                scanf("%s",s);
            for(int j = 0;j<Nc;j++){
                if(s[j] == 'S'){vis[i][j] = 1;maps[i][j] = 0;st = i*Nc + j;}
                else if(s[j] == '.'){maps[i][j] = 0;block++;}
                else if(s[j] == 'X'){maps[i][j] = 1;}
                else if(s[j] == 'D'){maps[i][j] = 0;ex = i,ey = j;en = i*Nc + j;}
            }
        }
        for(int i = T;i<=block;i+=T){if(ok){break;}else dfs(st,0,i);}
        if(ok)printf("YES\n");
        else printf("NO\n");
    }
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章