1018 Tempter of the Bone

1018 Tempter of the Bone

题意:一个n*m的矩阵中,“S”代表人,“X”为墙,“.”为路,“D”为门,在第T秒时门打开,那么“S”是否能够在第T秒到达门中。

思路:深搜,对于满足要求的点,进一步搜索,直到满足题意。

感想:看到题目第一眼,想法有些过于简单了,网上搜了一下,找到了奇偶剪枝,其中t-cnt为剩余的步数或者说时间,令其为T,s1+s2为剩余步数,令其为S,如果走偶数步要求的时间是奇数,或者走奇数步要求的时间是偶数,都明显不可行,而轻易得出奇数-偶数 = 奇数,反之亦然,而奇数-奇数= 偶数,偶数-偶数=偶数,所以tem必须为偶数。

#include<iostream>

#include<string.h>

#include<math.h>

#include<stdio.h>

using namespace std;

char map[10][10];

int n,m,t,di,dj,wall,flag;

int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};

void dfs(int si,int sj,int cnt){

   int i,tmp;

   if(si<1||si>n||sj<1||sj>m)

       return ;

   if(cnt==t&&si==di&&sj==dj)

       flag=1;

   if(flag)

       return ;

   int s1=si-di;

   int s2=sj-dj;

   if(s1<0) s1=-s1;

   if(s2<0) s2=-s2;

   tmp=t-cnt-s1-s2;

   if(tmp<0||tmp&1)

       return ;

   for(i=0;i<4;i++){

           if(map[si+dir[i][0]][sj+dir[i][1]]!='X'){

           map[si+dir[i][0]][sj+dir[i][1]]='X';

           dfs(si+dir[i][0],sj+dir[i][1],cnt+1);

           map[si+dir[i][0]][sj+dir[i][1]]='.';

       }

    }

   return ;

}

int main(){

   int i,j,sum,si,sj;

   while(cin>>n>>m>>t){

           wall=0;

       if(!n&&!m&&!t) break;

       for(i=1;i<=n;i++){

       for(j=1;j<=m;j++){

           cin>>map[i][j];

           if(map[i][j]=='S'){

                si=i;

                sj=j;

           }

           else if(map[i][j]=='D'){

                di=i;

                dj=j;

           }

           else if(map[i][j]=='X')

                wall++;

       }

       getchar();

       }

       if(n*m-wall<=t){

                printf("NO\n");

                continue;

       }

       flag=0;

       map[si][sj]='X';

       dfs(si,sj,0);

       if(flag)

           printf("YES\n");

       else

           printf("NO\n");

    }

   return 0;

}

你可能感兴趣的:(1018 Tempter of the Bone)