zoukankan      html  css  js  c++  java
  • FZU2150

    题意:

    给出(T)组数据,每组数据给出(N)(M),表示接下去(N)(M)列。
    图中“#”代表草,可以点燃;“.”点代表不能点燃;“#”和“.”都以走。
    现在需要同时点两把火(位置可以重合),火的燃烧方向是上下左右,可以同时进行(注意!:不是一次只能一个方向,可以同时上下左右)。
    若能烧完所有草(#),则输出最少时间,否则输出-1。

    思路:

    首先需要特判,如果草#的个数小于等于2的话,直接输出零(因为意味着点火的地方直接着了,无需耗费时间)。
    否则,
    因为是同时点燃两把火,所以相当于是双起点的BFS。
    所以,我们先把草#用结构体存储起来,然后双for循环让每个草之间去进行一个BFS比较最短时间。
    在BFS判断的时候,可以先让两个起点都入队,然后就是正常的BFS写法。

    AC代码:

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<cmath>
    #include<list>
    #include<stdlib.h>
    #include<map>
    #include<stack>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    #define sc(T) scanf("%d",&T)
    #define scc(x,y) scanf("%d %d",&x,&y)
    #define pr(T) printf("%d
    ",T)
    #define f(a,b,c) for (int a=b;a<=c;a++)
    #define ff(a,b,c) for (int a=b;a>=c;a--)
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define eps 1e-9
    #define PI acos(-1)
    
    int n,m,p;
    char a[12][12];
    bool book[12][12];
    int to[4][2]={{1, 0},{-1,0},{0, 1},{0, -1}};
    //int to[4][2]={0,1,1,0,-1,0,0,-1};
    struct node
    {
        int x,y,ss;
    }e[110],pp,qq;
    
    int bfs(node x,node y)
    {
        //book[x.x][x.y]=book[y.x][y.y]=1;
        queue<node> Q;
        x.ss=0,y.ss=0;
        Q.push(x),Q.push(y);
        book[x.x][x.y]=1;
        book[y.x][y.y]=1;
        // int ans=0;
        int cnt=2;
        while(!Q.empty())
        {
            pp=Q.front();
            Q.pop();
            //   ans=pp.ss;
            for(int i=0;i<4;i++)
            {
                qq=pp;
                qq.x+=to[i][0];
                qq.y+=to[i][1];
                qq.ss+=1;
                if(qq.x>=0&&qq.x<n&&qq.y>=0&&qq.y<m&&!book[qq.x][qq.y]&&a[qq.x][qq.y]!='.') //先判边界防止越界,或者单独写一个judge函数
                {
                    book[qq.x][qq.y]=1;
                    cnt++;
                    Q.push(qq);
                    if(cnt==p) // 说明所有数量的草#(数量为p)已经全部点燃了
                        return qq.ss; // 返回最小步数,也就是最短时间。
                }
            }
        }
        // return ans;
        return inf;
    }
    
    int main()
    {
        int T,cas=1;
        sc(T);
        while(T--)
        {
            scc(n,m);
            p=0;
            for(int i=0;i<n;i++)
            {
                scanf("%s",a[i]);
                for(int j=0;j<m;j++)
                {
                    if(a[i][j]=='#')// # grass
                    {
                        e[p].x=i;
                        e[p++].y=j;
                    }
                }
            }
            if(p<=2)//特判 最多只有两个# 别忘了输出      不特判的话WA
            {
                printf("Case %d: 0
    ",cas++);
                continue;
            }
            int mi=inf;
            for(int i=0;i<p;i++)
            {
                for(int j=i+1;j<p;j++)//0 save time
                {
                    mem(book,0);
                    int w=bfs(e[i],e[j]);
                    mi=min(w,mi);
                }
            }
            if(mi==inf)
                printf("Case %d: -1
    ",cas++);
            else
                printf("Case %d: %d
    ",cas++,mi);
        }
        return 0;
    }
    
  • 相关阅读:
    278.First Bad Version
    277. Find the Celebrity
    256.Paint House
    276. Paint Fence
    275. H-Index II
    274. H-Index
    273. Integer to English Words
    272. Closest Binary Search Tree Value II
    270. Closest Binary Search Tree Value
    271. Encode and Decode Strings
  • 原文地址:https://www.cnblogs.com/OFSHK/p/13379380.html
Copyright © 2011-2022 走看看