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

127 篇文章 0 订阅

一道DFS入门题,需要注意的是剪枝很多,,,,开始一看本以为用BFS就可以搞定,,但是测试数据就是不过,,,后来又看了看题,,原来要求的是刚好在T时间到达,而BFS求的是需要的最少时间。。。DFS找到所有情况后看是否有木有T时间到达的,,此外DFS还牵涉到回溯。。。。

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
char map[9][9];
typedef struct
{ int x;
  int y;
}Node;
Node s,e;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
bool flag;
int n,m,T;
void dfs(int a,int b,int t)
{  if(a==e.x&&b==e.y&&t==T) flag=true;
   if(flag) return;
   if(t>=T) return;
   if(abs(abs(a-e.x)+abs(b-e.y)-(T-t))%2!=0) return;
   if(a<=0||a>n||b<=0||b>m) return;
   for(int i=0;i<4;++i)
   { int xx=dx[i]+a;
     int yy=dy[i]+b;
     if(map[xx][yy]!='X')
     {  map[xx][yy]='X';
         dfs(xx,yy,t+1);
         map[xx][yy]='.';
     }
   }
   return;
}
int main()
{ while(~scanf("%d%d%d",&n,&m,&T)&&n&&m&&T)
{         getchar();
    for(int i=1;i<=n;++i)
         for(int j=1;j<=m;++j)
         { cin>>map[i][j];
           if(map[i][j]=='S') {s.x=i;s.y=j;}
           if(map[i][j]=='D')  {e.x=i;e.y=j;}
         }
    if(abs(abs(s.x-e.x)+abs(s.y-e.y)-T)%2!=0||(abs(s.x-e.x)+abs(s.y-e.y))>T) {cout<<"NO"<<endl;continue;}
      flag=false;
     map[s.x][s.y]='X';
       dfs(s.x,s.y,0);
        map[s.x][s.y]='.';
        if(flag) cout<<"YES"<<endl;
        else    cout<<"NO"<<endl;
        }return 0;
}

苦逼的BFS:

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
typedef struct
{ int x;
  int y;
}Node;
char map[8][8];
int a[8][8];
bool visit[8][8];
Node s,e;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
int n,m,tim;
int ans;
queue<Node>Q;
bool bfs()
 {
	 while(!Q.empty())
	 {  s=Q.front();
	      Q.pop();
		  for(int i=0;i<4;++i)
		  { int xx=s.x+dx[i];
		    int yy=s.y+dy[i];
			if(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]&&!visit[xx][yy])
			{     ans++;
				if(xx==e.x&&yy==e.y) 
			   { if(ans>tim) return false;
			     else  return true;
			    }
			    if(ans>=tim) return false; 
			    visit[xx][yy]=true;
				s.x=xx;s.y=yy;
				Q.push(s);
            }
		  }
	 }
	 return false;
}
int main()
{ 
  while(cin>>n>>m>>tim&&n&&m&&tim)
  {   ans=0;
	  memset(visit,false,sizeof(visit));
      memset(a,0,sizeof(a));
      for(int i=0;i<n;++i)
		   for(int j=0;j<m;++j)
			  { cin>>map[i][j];
	            if(map[i][j]=='X') a[i][j]=0;
				else if(map[i][j]=='S') {s.x=i;s.y=j;}
				else if(map[i][j]=='D')  {e.x=i;e.y=j;a[i][j]=1;}
				else  a[i][j]=1;
               }
	   Q.push(s);
	  visit[s.x][s.y]=true;
	  if(bfs()) cout<<"YES"<<endl;
	  else      cout<<"NO"<<endl;
  }return 0;
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值