HDOJ 1044 BFS+DFS

7 篇文章 0 订阅
6 篇文章 0 订阅

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1044
题目大概意思就是一个迷宫L步之内找价值最多的宝石并且到出口。
最开始我用了dfs LTE。bfs我感觉不适用这个题。求最大值肯定是要类似于dp的思想,搜索里面肯定是dfs才能实现。然后发现其实这就是,这几个宝石可以当做路口,然后每个路口加个分,问L步之内最多多少分。也就是可以当成树。然后就是建树,每个路口之间都有很多路。当然是要最短路喽。然后最短路就可以用bfs解决(快啊)。然后就用bfs遍历一次所有点。然后再用dfs进行搜索。注意value【M+1】记得初始化。因为value是当宝石价值,但是dfs中M点(出口)最后一次也会加一次。不初始化,假设上次宝石数比这次多久出问题了。这道题因为这个bug卡了我很久。尴尬。

#include<bits/stdc++.h>
#define PI 3.1415926
#define INF 1e18
#define inf 1e9
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std ;
typedef long long ll;
typedef unsigned long long ull;
const int _max = 55;
struct node{
    int x,y;
    int step;
    void init(int x,int y,int step){
        this->x=x;
        this->y=y;
        this->step=step; 
    }
};
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int value[_max];
char mp[_max][_max];
char vis[_max][_max];
int n_mp[_max][_max];
bool n_vis[_max];
int w,h,l,m;
int ans,sum;
queue<node> q;
bool outside(node n1){
    if(mp[n1.y][n1.x] == '*') return false;
    else if(n1.y < 1) return false;
    else if(n1.y > h) return false;
    else if(n1.x > w) return false;
    else if(n1.x < 1) return false;
    else if(!vis[n1.y][n1.x]) return false;
    return true;
}
void bfs(int a,int x,int y){
    while(!q.empty()) q.pop();
    node now,next;
    now.init(x,y,0);
    q.push(now);
    vis[y][x] = false;
    while(!q.empty()){
        now = q.front();
        q.pop();
        for(int i = 0 ; i < 4 ; i++){
            next.init(now.x+dx[i],now.y+dy[i],now.step+1);
            if(next.step > l) continue;
            if(!outside(next)) continue;
            char c = mp[next.y][next.x];
            if(c == '@') n_mp[a][0]=next.step;
            else if(c == '<') n_mp[a][m+1]=next.step;
            else if(c >= 'A' && c <= 'J') n_mp[a][c-'A'+1]=next.step;
            vis[next.y][next.x] = false;
            q.push(next);
        }   
    }
    return ;
} 
void dfs(int n,int cnt,int step){
    if(step > l) return ;
    if(sum == ans) return ;
    if(n == m+1){
        ans = max(cnt,ans);
        return ;
    }
    for(int i = 1 ; i <= m+1 ; i++){
        if(!n_vis[i]) continue;
        if(!n_mp[n][i]) continue;
        n_vis[n] = false;
        dfs(i,cnt+value[i],step+n_mp[n][i]);
        n_vis[i] = true;
    }
    return ;
}
int main(){
    int T,t=1;
    cin>>T;
    while(T--){
        cin>>w>>h>>l>>m;
        sum = 0;
        memset(n_mp,0,sizeof(n_mp));
        memset(n_vis,true,sizeof(n_vis));
        memset(value,0,sizeof(value));
        for(int i = 1 ; i <= m ; i++){
            cin>>value[i];
            sum += value[i];
        }
        for(int y = 1 ; y <= h ; y++)
            for(int x = 1 ; x <= w ; x++)
                cin>>mp[y][x];
        for(int y = 1 ; y <= h ; y++)
            for(int x = 1 ; x <= w ; x++){
                memset(vis,true,sizeof(vis));
                char c = mp[y][x];
                if(c == '@') bfs(0,x,y);
                else if(c == '<') bfs(m+1,x,y);
                else if(c >= 'A' && c <= 'J') bfs(c-'A'+1,x,y);
            }   
    /*  for(int y = 0 ; y <= m+1 ; y++){
            for(int x = 0 ; x <= m+1 ; x++){
                cout<<n_mp[y][x]<<" ";
            }
            cout<<endl;
        }*/
        cout<<"Case "<<t++<<":"<<endl;
        if(n_mp[0][m+1] > l ){
            cout<<"Impossible"<<endl;
            continue;
        }
        ans = -inf;
        dfs(0,0,0);
        if(ans == -inf)
            cout<<"Impossible"<<endl;
        else 
            cout<<"The best score is "<<ans<<"."<<endl;
        if(T)cout<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值