zoukankan      html  css  js  c++  java
  • 礼物(BFS)

    礼物

    时间限制: 1 Sec  内存限制: 64 MB
    提交: 39  解决: 4
    [提交][状态][讨论版]

    题目描述

       给出一个n行m列的点阵,“.”表示可通行格子,“#”表示不可通行格子,“K”表示国王的初始位置,“Q”表示王后的位置,“G”表示该格子有一个礼 物。注意:国王、王后、礼物所在的格子可以认为是可通行格子。国王从开始位置出发,国王从当前格子可以走到上、下、左、右四个相邻格子,当然前提是可通行 格子。国王从当前格子走到相邻格子的时间是变化的,这取决于国王手头上收集到的礼物的数量,假如当前国王手头上有y个礼物,那么他从当前格子移动到相邻格 子的所用时间是y+l秒。一旦国王进入某个有礼物的格子,他可以选择取该格子的礼物,也可以选择不取该格子的礼物。取礼物这个动作可以认为是瞬间完成的, 不需要时间。国王想收集到尽量多的礼物送给王后,但是他到达王后所在的格子不能超过T秒,王后不想等太长时间。注意:国王在收集礼物的途中可能多次走到相 同的格子。

    输入

      第1行:三个整数n、m、T。 1≤n,m≤50,1≤T≤109。
      接下来是n行m列的点阵,‘G’的数量不超过16。只有一个国王,一个王后。

    输出

    一个整数,国王在规定时间内,最多可以收集到多少个礼物送给王后?

    样例输入

    5 7 50
    #....G#
    ###G###
    #K...Q#
    ###.###
    #G..GG#
    

    样例输出

    4
    【分析】威哥写的,表示并不懂,立个flag,日后再学,已经看晕了。
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <list>
    #include<functional>
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define pi acos(-1.0)
    using namespace std;
    typedef long long ll;
    const int N = (1<<16)+5;
    const int INF = 0x3f3f3f3f;
    char s[52][52];
    int n,m,T;
    struct Node {
        int x,y;
        Node(int a=0,int b=0) {
            x=a;
            y=b;
        }
    } st,ed;
    vector<Node>g;
    int d[18][18],dis[51][51],f[N][16];
    int dx[4]= {0,0,-1,1};
    int dy[4]= {-1,1,0,0};
    void bfs(int pos) {
        queue<Node>q;
        memset(dis,INF,sizeof(dis));
        dis[g[pos].x][g[pos].y]=0;
        q.push(g[pos]);
        while(!q.empty()) {
            Node u=q.front();
            q.pop();
            for(int i=0; i<4; ++i) {
                int x=u.x+dx[i],y=u.y+dy[i];
                if(x<1||x>n||y<1||y>m||s[x][y]=='#')continue;
                if(dis[x][y]==INF) {
                    dis[x][y]=dis[u.x][u.y]+1;
                    q.push(Node(x,y));
                }
            }
        }
        for(int i=0; i<g.size(); ++i)if(i!=pos) {
                d[pos][i]=dis[g[i].x][g[i].y];
            }
    }
    int main() {
        scanf("%d%d%d",&n,&m,&T);
        for(int i=1; i<=n; ++i)scanf("%s",s[i]+1);
        for(int i=1; i<=n; ++i) {
            for(int j=1; j<=m; ++j) {
                if(s[i][j]=='K')st=Node(i,j);
                else if(s[i][j]=='Q')ed=Node(i,j);
                else if(s[i][j]=='G')g.push_back(Node(i,j));
            }
        }
        g.push_back(st);
        g.push_back(ed);
        memset(d,INF,sizeof(d));
        memset(f,INF,sizeof(f));
        for(int i=0; i<g.size()-1; ++i)bfs(i);
        int ss=g.size()-2,tt=g.size()-1,tot=(1<<(g.size()-2));
        for(int i=0; i<g.size()-2; ++i) {
            f[1<<i][i]=d[ss][i];
        }
        for(int i=1; i<tot; ++i) {
            for(int j=0; j<g.size()-2; ++j) {
                if(!(i&(1<<j))||f[i][j]>=INF)continue;
                for(int k=0; k<g.size()-2; ++k) {
                    if((i&(1<<k))||d[j][k]>=INF)continue;
                    f[i|(1<<k)][k]=min(f[i][j]+(__builtin_popcount(i)+1)*d[j][k],f[i|(1<<k)][k]);
                }
            }
        }
        int ret=0;
        for(int i=1; i<tot; ++i) {
            for(int j=0; j<g.size()-2; ++j) {
                if(f[i][j]!=INF||d[j][tt]!=INF) {
                    int tmp=f[i][j]+(__builtin_popcount(i)+1)*d[j][tt];
                    if(tmp<=T) ret=max(ret,__builtin_popcount(i));
                }
            }
        }
        printf("%d
    ",ret);
        return 0;
    }
    View Code
  • 相关阅读:
    [DNN模块] DNNPortalDownload_1_0_9a_PA(C#)汉化版
    我的第一个DNN皮肤
    调试DNN的方法
    DotNetNuke系列文章 Skin 與 Container 設計介紹
    DotNetNuke 語言包的上傳步驟
    pstools使用说明
    Android Prefence 总结
    android 来电自动接听和自动挂断
    Android 颜色选择器(ColorPicker)
    修改文件权限与归属
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/5726244.html
Copyright © 2011-2022 走看看