• HDU 1983 Kaitou Kid


    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
     
        这题既要用dfs,有要用bfs。dfs搜索要封锁的区域个数,bfs搜索Kid能否盗取宝石。很容易知道封锁的区域最多有4个,因为给入口或者出口围住最多只要4个区域,那么就可以给最大值设成4,然后去搜。
     
        
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    struct p
    {
        int x,y,t,su;
        int s1[90],s2[90];
    };
    int n,m,sx,sy,ans,time;
    char map[10][10];
    int v[10][10][2];
    int yi[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    void dfs(int k)
    {
        queue<p>q;
        p f,r;
        int vis=-1,i,j;
        if (k>ans) return ;
        f.x=sx;
        f.y=sy;
        f.t=0;
        f.su=0;
        memset(v,0,sizeof(v));
        while (!q.empty()) q.pop();
        v[sx][sy][0]=1;
        q.push(f);
        while (!q.empty())
        {
            r=q.front();
            q.pop();
            if (r.t>time) continue;
            if (map[r.x][r.y]=='E'&&r.su) {vis=r.t;break;}
            f.t=r.t+1;
            f.su=r.su;
            for (i=0;i<4;i++)
            {
                f.x=r.x+yi[i][0];
                f.y=r.y+yi[i][1];
                if (f.x>=0&&f.x<n&&f.y>=0&&f.y<m&&map[f.x][f.y]!='#')
                {
                    if (map[f.x][f.y]=='J') f.su=1;
                    else f.su=r.su;
                    if (v[f.x][f.y][f.su]) continue;
                    v[f.x][f.y][f.su]=1;
                    for (j=1;j<=r.t;j++)
                    {
                        f.s1[j]=r.s1[j];
                        f.s2[j]=r.s2[j];
                    }
                    f.s1[f.t]=f.x;
                    f.s2[f.t]=f.y;
                    q.push(f);
                }
            }
        }
        if (vis==-1)
        {
            if (ans>k) ans=k;
            return ;
        }
        for (i=1;i<=r.t;i++)
        {
            char c=map[r.s1[i]][r.s2[i]];
            if (c=='S'||c=='E') continue;
            map[r.s1[i]][r.s2[i]]='#';
            dfs(k+1);
            map[r.s1[i]][r.s2[i]]=c;
        }
    }
    int main()
    {
        int c,i,j;
        scanf("%d",&c);
        while (c--)
        {
            scanf("%d%d%d",&n,&m,&time);
            for(i=0;i<n;i++)
            for(j=0;j<m;j++)
            {
                scanf(" %c",&map[i][j]);
                if (map[i][j]=='S') {sx=i;sy=j;}
            }
            ans=4;
            dfs(0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    24. Swap Nodes in Pairs(M);25. Reverse Nodes in k-Group(H)
    61. Rotate List(M);19. Remove Nth Node From End of List(M)
    素数筛选法(prime seive)
    哈夫曼树;二叉树;二叉排序树(BST)
    sort与qsort的区别与联系
    贪心算法
    First non-repeating character in a stream
    transform
    C++11 & C++14 & C++17新特性
    开个玩笑
  • 原文地址:https://www.cnblogs.com/pblr/p/4713403.html
Copyright © 2020-2023  润新知