深度优先搜索题集(迷宫类型)

 

hdu1010(小狗逃迷宫)

 

题意:在一个迷宫中有一只小狗和一根骨头,然后在T分钟的时候恰好迷宫的出口会打开,然后问小狗是否能在第T分钟的时候到达出口离开迷宫。

 

小狗可以向上下左右四个方向移动,然后小狗不能走回头路,即已经走过了的路就不能再走,并且小狗只能一直走,不能停下来。

奇偶剪枝!

再用n*m-wall剪枝!(可以走的格子不能比t小)

AC:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,mt,flag,wall;
int sx,sy,ex,ey;
char mp[10][10];
int vis[10][10];
int tx[4]={1,0,-1,0};
int ty[4]={0,1,0,-1};


void dfs(int x,int y,int t)
{
 int minx=abs(ex-x)+abs(ey-y);///奇偶剪枝
 if(t<minx||(t-minx)%2) return ;
 if(x==ex&&y==ey)
 {
  if(t==0)
    flag=1;
  return ;
 }
 for(int i=0;i<4;i++)
 {
  int dx=x+tx[i];
  int dy=y+ty[i];
  if(dx>=0&&dx<n&&dy>=0&&dy<m)
      if(!vis[dx][dy]&&mp[dx][dy]!='X')
      {
          vis[dx][dy]=1;
          dfs(dx,dy,t-1);
          if(flag) return ;
          vis[dx][dy]=0;
      }
 }
}


int main()
{
 while(scanf("%d%d%d",&n,&m,&mt))
 {
     wall=flag=0;
     memset(mp,0,sizeof(mp));
     memset(vis,0,sizeof(vis));
     if(n==0&&m==0&&mt==0) break;
     for(int i=0;i<n;i++)
         scanf("%s",&mp[i]);
     for(int i=0;i<n;i++)
         for(int j=0;j<m;j++)
         {
             if(mp[i][j]=='S')
                 sx=i,sy=j;
             else if(mp[i][j]=='D')
                 ex=i,ey=j;
             else if(mp[i][j]=='X')
                wall++;
         }
     if(n*m-wall<=mt)///可以走的格子不能比t少
     {
         cout<<"NO"<<endl;
         continue;
     }
     vis[sx][sy]=1;
     dfs(sx,sy,mt);
     if(!flag) printf("NO\n");
     else printf("YES\n");
 }
  return 0;
}

 

 

求水洼数目(poj2386)

 

题目描述:

给定一个矩阵(m*n),其中W表示有水,. 表示干地,现给出定义在W周围(包括该W)的8个坐标位置(上下左右,左上左下右上右下)有W存在则形成水洼(水洼具有传递性),求这个矩阵中有多少个水洼?

样例输入:

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

样例输出:

3

#include<bits/stdc++.h>  
using namespace std;  
char s[101][101];  
void dfs(int x,int y)  
{  
 s[x][y]='.';//将积水变干  
 for(int i=-1;i<=1;i++)//遍历周围8个方向是否有积水,有积水就递归  
   for(int j=-1;j<=1;j++)  
     {  
      int dx=x+i,dy=y+j;  
      if(s[dx][dy]=='#')  
        dfs(dx,dy);  
     }  
    return ;  
}  
int main()  
{  
  int n,m;  
  while(scanf("%d%d",&n,&m));  
  {  
    for(int i=0;i<n;i++)  
      for(int j=0;j<m;j++)  
        cin>>s[i][j];  
    int sum=0;  
    for(int i=0;i<n;i++)  
      for(int j=0;j<m;j++)  
       {  
        if(s[i][j]=='#')  
         {  
          sum++;  
          dfs(i,j);  
         }  
       }  
    cout<<sum<<endl;  
 }  
 return 0;  
}  

 

 

小q的口袋乐园(dfs,贪心)

 

 

周末,小Q喜欢在PU口袋校园上参加各种活动刷绩点,体验丰富多彩的大学生活。

但是每个活动有各自的开始时间、结束时间、Happy值以及绩点数,活动之间可能存在时间冲突。

小Q是一个认真踏实的女孩,她在同一时间只会参加一个活动。

给出每一天的活动数,求小Q在同一天内所能获得的最大Happy值 与 绩点数。

小Q是一个活泼开朗的女孩,她总是寻求最大的Happy值,如果Happy值相同,才会尽可能使绩点数更多。

输入描述:

第一行输入一个整数T(表示样例个数)
接下来T组样例
每组样例第一行输入一个整数N(表示有几项活动)
接下来N行,每行输入s,e,h,p 4个整数,分别代表一个活动的开始时间、结束时间、Happy值以及绩点数
0<=s<e<=24,1<=h,p<=100,1<=T,N<=20

输出描述:

输出T行
一行输出一个样例对应的结果
小Q在一天内所能获得的最大 Happy值 与 绩点数

AC:

#include<iostream>  
#include<cstring>  
#include<cstdio>  
using namespace std;  
struct node{  
int st,ed,hp,cj;  
}ac[10240];  
int hp2,cj2,n;  
int vis[10240];  
  
void dfs(int bg,int hp1,int cj1)  
{  
 if(hp1>hp2)  
  hp2=hp1,cj2=cj1;  
 else if(hp1==hp2&&cj1>cj2)  
  hp2=hp1,cj2=cj1;  
 for(int i=0;i<n;i++)  
 {  
  if(!vis[i]&&ac[i].st>=bg)  
  {  
   vis[i]=1;  
   dfs(ac[i].ed,hp1+ac[i].hp,cj1+ac[i].cj);  
   vis[i]=0;  
  }  
 }  
 return ;  
}  
  
int main()  
{  
 int t,a,b,c,d;  
 cin>>t;  
 while(t--){  
  hp2=cj2=0;  
  memset(vis,0,sizeof(vis));  
  cin>>n;  
  for(int i=0;i<n;i++)  
    cin>>ac[i].st>>ac[i].ed>>ac[i].hp>>ac[i].cj;  
  dfs(0,0,0);  
  cout<<hp2<<" "<<cj2<<endl;  
 }  
 return 0;  
}  

 

Rescue

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 35535    Accepted Submission(s): 12326

 


 

Problem Description

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)

 

 

Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.

 

 

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."

 

 

Sample Input

 

7 8#.#####.#.a#..r.#..#x.....#..#.##...##...#..............

 

Sample Output

 

13

AC:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,flag,ans;
int vis[205][205];
char mp[205][205];
int tx[4]={1,0,-1,0};
int ty[4]={0,-1,0,1};

void dfs(int x,int y,int step)
{
 if(mp[x][y]=='x')
   step++;
 if(mp[x][y]=='r')
 {
  flag=1;
  if(step<ans)
    ans=step;
  return ;
 }
 vis[x][y]=1;
 for(int i=0;i<4;i++)
 {
  int dx=x+tx[i],dy=y+ty[i];
  if(!vis[dx][dy]&&mp[dx][dy]!='#')
    if(dx>=0&&dy>=0&&dx<n&&dy<m)
    {
       dfs(dx,dy,step+1);
       vis[dx][dy]=0;
    }
 }
}

int main()
{
 while(scanf("%d%d",&n,&m)!=EOF)
 {
  memset(mp,0,sizeof(mp));
  memset(vis,0,sizeof(vis));
  ans=99999;
  for(int i=0;i<n;i++)
    scanf("%s",&mp[i]);
  for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
       if(mp[i][j]=='a')
         {
          dfs(i,j,0);
          break;
         }
  if(ans==99999)
    printf("Poor ANGEL has to stay in the prison all his life.\n");
  else printf("%d\n",ans);
 }
 return 0;
}

传送门:迷宫类型深搜(dfs,深度优先搜索)

 

转载于:https://www.cnblogs.com/wangtao971115/p/10358380.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值