hdu2102-A计划-dfs剪枝|bfs

https://vjudge.net/problem/HDU-2102
王子在第一层的1,1,公主在p点,问能否在规定时限内达到。
因为是最短,自然想到用bfs。wa了无数次。以下错误
1 在判断跳的时候也要判断x和y的范围。
2 王子在1,1啊 ,不是在s点。。(有的数据没有s点这个提示,样例误导人啊,我还在分情况呢,后来发现无所谓)
3 关于计数的问题,自然的写法是不会算跳层的时间的,自然写就行、
4 会存在达不到的情况。。
5 用dfs的时候,如果直接爆搜会tle。。(如果不tle反而会觉得有点怪。。首先是时间限制,其次是如果已经达到就不用再比了oyeah)
bfs版本
pair的四个变量分别是 层数,步数,x坐标,y坐标。
bfs dfs一样。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=12;
int m,n,t;
int fx[2][4]{{1,-1,0,0},{0,0,1,-1}};
bool vis[2][maxn][maxn];
int main()
{   int T;
   char a[2][maxn][maxn];
    cin>>T;
    while(T--){
         cin>>m>>n>>t;
         memset(vis,false,sizeof(vis));
         queue<pair<pair<int,int>,pair<int,int> > > q;
         for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                 cin>>a[0][i][j];
             }
         }
         for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                 cin>>a[1][i][j];

             }
         }
         q.push(make_pair(make_pair(0,0),make_pair(1,1)));
                     vis[0][1][1]=true;
         bool flag=false;
          while(!q.empty())
         {   pair<pair<int,int>,pair<int,int > > u=q.front();
              q.pop();
               if(a[u.first.first][u.second.first][u.second.second]=='P')
               { //puts("!!!!!!jiangxiansheng");
                   if(u.first.second<=t)
                  { //cout<<u.first.second<<endl;
                      puts("YES");
                  flag=true;
                  }
               }
              for(int i=0;i<4;i++){
                  int x=fx[0][i]+u.second.first;
                  int y=fx[1][i]+u.second.second;
                  if(x>=1&&x<=m&&y>=1&&y<=n&&a[u.first.first][x][y]=='#'&&(a[1-u.first.first][x][y]=='.'||a[1-u.first.first][x][y]=='P')&&!vis[u.first.first][x][y]&&!vis[1-u.first.first][x][y])
    {  vis[u.first.first][x][y]=true;
        vis[!u.first.first][x][y]=true;
        q.push(make_pair(make_pair(1-u.first.first,u.first.second+1),make_pair(x,y)));
    }else if(!vis[u.first.first][x][y]&&x>=1&&x<=m&&y>=1&&y<=n&&(a[u.first.first][x][y]=='P'||a[u.first.first][x][y]=='.')){
                      vis[u.first.first][x][y]=true;
                      q.push(make_pair(make_pair(u.first.first,u.first.second+1),make_pair(x,y)));
    }
              }

         }
         /*for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++)
            { if(vis[0][i][j])
               printf("* ");
               else
                printf("! ");

            }
            cout<<endl;
         }
         cout<<"!!!!!!!!!!!!!!!!!!!!!!"<<endl;
         for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++)
            { if(vis[1][i][j])
               printf("* ");
               else
                printf("! ");

            }
            cout<<endl;
         }*/

         if(!flag)
         puts("NO");

    }
    return 0;
}

用 pair类型传参数,开始错在了宏定义用first,和pair重名了。qwq,后来改成了one



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#define one u.first.first
#define two u.first.second
#define three u.second.first
#define four u.second.second
using namespace std;
const int maxn=12;
int m,n,t;
int fx[2][4]{{1,-1,0,0},{0,0,1,-1}};
bool vis[2][maxn][maxn];
char a[2][maxn][maxn];
int tttt;
bool f;
void dfs( pair< pair<int,int>, pair<int,int > >  u){
     //pair< pair<int,int>, pair<int,int > >  u;
     if(two>t) return ;
     if(f) return ;
     //u=make_pair(make_pair(a1,b),make_pair(c,d));
     if(a[one][three][four]=='P')
     {   tttt=min(two,tttt);
        if(tttt<=t) f=1;
     return ;
     }
     for(int i=0;i<4;i++){
         int x=fx[0][i]+three;
         int y=fx[1][i]+four;
         if(x>=1&&x<=m&&y>=1&&y<=n&&a[one][x][y]=='#'&&(a[!one][x][y]=='.'||a[!one][x][y]=='P')&&!vis[!one][x][y]&&!vis[one][x][y])
         {  vis[one][x][y]=true;
            vis[!one][x][y]=true;
            dfs(make_pair(make_pair(!one,two+1),make_pair(x,y)));
            vis[one][x][y]=false;
            vis[!one][x][y]=false;
         }
         else if(x>=1&&x<=m&&y>=1&&y<=n&&!vis[one][x][y]&&(a[one][x][y]=='P'||a[one][x][y]=='.'))
          {  vis[one][x][y]=true;
              dfs(make_pair(make_pair(one,two+1),make_pair(x,y)));
             vis[one][x][y]=false;
          }
     }
}
int main()
{   int T;
    cin>>T;
    while(T--){
         cin>>m>>n>>t;
         memset(vis,false,sizeof(vis));
         tttt=0x3f3f3f3f;
         f=false;
         queue<pair<pair<int,int>,pair<int,int> > > q;
         for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                 cin>>a[0][i][j];
             }
         }
         for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                 cin>>a[1][i][j];
             }
         }
                     vis[0][1][1]=true;
          dfs(make_pair(make_pair(0,0),make_pair(1,1)));
          if(tttt<=t)
            puts("YES");
          else
            puts("NO");

         /*for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++)
            { if(vis[0][i][j])
               printf("* ");
               else
                printf("! ");
            }
            cout<<endl;
         }
         cout<<"!!!!!!!!!!!!!!!!!!!!!!"<<endl;
         for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++)
            { if(vis[1][i][j])
               printf("* ");
               else
                printf("! ");

            }
            cout<<endl;
         }
         puts("YES..");*/
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值