zoukankan      html  css  js  c++  java
  • hdu Kaitou Kid The Phantom Thief (2)

    Kaitou Kid - The Phantom Thief (2)

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 67    Accepted Submission(s): 39
     
    Problem Description
    破解字迷之后,你得知Kid将会在展览开始后T分钟内盗取至少一颗宝石,并离开展馆。整个展馆呈矩形分布,划分为N*M个区域,有唯一的入口和出口(不能从出口进入,同样不能从入口出去)。由某个区域可直接移动至相邻四个区域中的一个,且最快需要一分钟。假设Kid进入放有宝石的区域即可盗取宝石,无需耗时。问至少要封锁几个区域(可以封锁放有宝石的区域,但不能封锁入口和出口)才能保证Kid无法完成任务。
     
    Input
    输入的第一行有一个整数C,代表有C组测试数据。每组测试数据的第一行有三个整数N,M,T(2<=N,M<=8,T>0)。接下来N行M列为展馆布置图,其中包括:
    'S':入口 'E':出口 'J':放有宝石的区域,至少出现一次 '.':空白区域 '#':墙
     
    Output
                对每组测试数据,输出至少要封锁的区域数。
     
    Sample Input
    2
    5 5 5
    SJJJJ
    ..##J
    .JJJJ
    .J...
    EJ...
    5 5 6
    SJJJJ
    ..##J
    .JJJJ
    .J...
    
    EJ...
     
    Sample Output
    0
    2
     
    Author
    LL
     
    Source
    2008杭电集训队选拔赛
     
    Recommend
    wangye

    分析:最多封锁4个位置,所以从0枚举到3,直到KID无法完成任务。判断能否完成任务时,每个位置可能有两种情况:有无拿到宝石,这样设置一个二维的标记数组就能将回头的bfs转化为了不能回头的。如果直接用不回头的bfs法会MLE。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    typedef struct S {
        int order, time, J;
    } STEP;
    char map[100], s[10];
    int m, n, start;
    int dx[] = {0, 0, 1, -1};
    int dy[] = {1, -1, 0, 0};
    int vis[2][100];
    int t;
    
    int bfs() {
        int k, i, j, xx, yy, temp;
        STEP now, next;
        now.order = start;
        now.time = 0;
        now.J = 0;
        queue<STEP> q;
        memset(vis, 0, sizeof (vis));
        vis[0][start] = 1;
        q.push(now);
        while (!q.empty()) {
            now = q.front();
            q.pop();
            if (now.time >= t)
                continue;
            i = now.order / n;
            j = now.order % n;
            for (k = 0; k < 4; ++k) {
                xx = i + dx[k];
                yy = j + dy[k];
                temp = xx * n + yy;
                next.time = now.time + 1;
                if (xx >= 0 && xx < m && yy >= 0 && yy < n) {
                    if (map[temp] == 'E') {
                        if (now.J)
                            return 0;
                    }
                    if (map[temp] != '#') {
                        if (map[temp] == 'J')
                            next.J = 1;
                        else
                            next.J = now.J;
                        if (!vis[now.J][temp]) {
                            vis[now.J][temp] = 1;
                            next.order = temp;
                            q.push(next);
                        }
                    }
                }
            }
        }
        return 1;
    }
    
    int main() {
        int i, j, jd, T, ans;
        scanf("%d", &T);
        while (T--) {
            scanf("%d%d%d", &m, &n, &t);
            scanf("%*c");
            jd = 0;
            for (i = 0; i < m; ++i) {
                scanf("%s", s);
                for (j = 0; j < n; ++j) {
                    map[jd + j] = s[j];
                    if (s[j] == 'S')
                        start = jd + j;
                }
                jd += n;
            }
    
            int k;
            if (bfs()) {
                ans = 0;
                goto L;
            }
            char ch[3];
            for (i = 0; i < m * n; ++i) {
                if (map[i] == '#' || map[i] == 'S' || map[i] == 'E') {
                    continue;
                }
                ch[0] = map[i];
                map[i] = '#';
    
                if (bfs()) {
                    ans = 1;
                    goto L;
                }
                map[i] = ch[0];
            }
            for (i = 0; i < m * n; ++i) {
                if (map[i] == '#' || map[i] == 'S' || map[i] == 'E') {
                    continue;
                }
                ch[0] = map[i];
                map[i] = '#';
                for (j = i + 1; j < m * n; ++j) {
                    if (map[j] == '#' || map[j] == 'S' || map[j] == 'E') {
                        continue;
                    }
                    ch[1] = map[j];
                    map[j] = '#';
    
                    if (bfs()) {
                        ans = 2;
                        goto L;
                    }
                    map[j] = ch[1];
                }
                map[i] = ch[0];
            }
    
            for (i = 0; i < m * n; ++i) {
                if (map[i] == '#' || map[i] == 'S' || map[i] == 'E') {
                    continue;
                }
                ch[0] = map[i];
                map[i] = '#';
                for (j = i + 1; j < m * n; ++j) {
                    if (map[j] == '#' || map[j] == 'S' || map[j] == 'E') {
                        continue;
                    }
                    ch[1] = map[j];
                    map[j] = '#';
                    for (k = j + 1; k < m * n; ++k) {
                        if (map[k] == '#' || map[k] == 'S' || map[k] == 'E') {
                            continue;
                        }
                        ch[2] = map[k];
                        map[k] = '#';
                        if (bfs()) {
                            ans = 3;
                            goto L;
                        }
                        map[k] = ch[2];
                    }
                    map[j] = ch[1];
                }
                map[i] = ch[0];
            }
    
            ans = 4;
    L:
            printf("%d\n", ans);
        }
        return 0;
    
    
    }
  • 相关阅读:
    C#初识
    SQL 语言基础
    类;类型
    输入一元二次方程的三个参数,a,b,c,判断是否为一元二次方程,并求解
    输入一个1-100之内的数,判断是否跟7有关
    输入身高、体重、性别,判断是否是标准体重,男性标准=(身高-100)+-3,女性标准=(身高-110)+-3
    分别录入年月日,判断是否是一个正确的日期
    面向对象基础--面向对象思想(理解)
    2015-01-04 Javascript
    2014-12-28 iframe,style,body style
  • 原文地址:https://www.cnblogs.com/baidongtan/p/2666252.html
Copyright © 2011-2022 走看看