FZU 2150 Fire Game(BFS)

点我看题目

题意 :就是有两个熊孩子要把一个正方形上的草都给烧掉,他俩同时放火烧,烧第一块的时候是不花时间的,每一块着火的都可以在下一秒烧向上下左右四块#代表草地,.代表着不能烧的。问你最少花多少时间可以烧掉,如果烧不掉就输出-1

思路 :这个题因为可以同时向上下左右同时烧过去,所以一看我就知道是BFS,但是知道没用啊,我做不出来啊,我一开始没想过来,以为两个人烧很麻烦,其实就是向普通的那样做,不过来个6重for循环就行了,其实就是看看有几个块,如果块的个数超过两个就为-1,两个的话,分别开始烧,哪个块里有最长路,就是烧的那个时间,不过你要枚举有最长路的那个的块的每一个可烧的点,从而找出时间最短的,1个块的时候也是一样的,求出最长路,枚举每个点的时候求最短时间。这个题看着芳姐的代码才理解。。。。。

不过做的时候没有去判断几个块,因为你BFS找的时候就处理了。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>

const int INF = 99999999 ;
int n,m ;
char ch[15][15] ;
int cnt ;
int vis[110][110] ;
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}} ;
struct node
{
    int x,y ;
    int step ;
}q1,q2 ,mapp[150];

using namespace std ;

int BFS(int x1,int y1,int x2,int y2)
{
    int maxx = 0 ;
    queue<node>que ;
    q1.x = x1,q1.y = y1,q1.step = 0 ;
    q2.x = x2,q2.y = y2,q2.step = 0 ;
    que.push(q1) ;
    que.push(q2) ;
    //memset(vis,0,sizeof(vis)) ;
    while(!que.empty())
    {
        struct node st1, st = que.front() ;
        que.pop() ;
        for(int i = 0 ; i < 4 ; i++)
        {
            int xx = st.x+dir[i][0] ;
            int yy = st.y+dir[i][1] ;
            if(!vis[xx][yy] && ch[xx][yy] == '#' && (xx >= 0&&xx < n&&yy>=0&&yy<m))
            {
                vis[xx][yy] = 1 ;
                st1.x = xx ,st1.y = yy ,st1.step = st.step+1 ;
                que.push(st1) ;
            }
        }
        maxx = max(maxx,st.step) ;
    }
    return maxx ;
}

int main()
{
    int T ;
    scanf("%d",&T) ;
    for(int i = 1 ; i <= T ;i++)
    {
        scanf("%d %d",&n,&m) ;
        cnt = 0 ;
        for(int j = 0 ; j < n ; j++)
        {
            scanf("%s",ch[j]) ;
            for(int k = 0 ; k < m ; k++)
            if(ch[j][k] == '#')
            {
                cnt++ ;
                mapp[cnt].x = j ;
                mapp[cnt].y = k ;
            }
        }
        printf("Case %d: ",i) ;
        if(cnt <= 2 )
        {
            printf("0
") ;
            continue ;
        }
        int minn = INF ;
        for(int j = 0 ; j < cnt ; j++)
        {
            for(int k = j ; k < cnt ; k++)
            {
                memset(vis,0,sizeof(vis)) ;
                vis[mapp[j].x][mapp[j].y] = 1 ;
                vis[mapp[k].x][mapp[k].y] = 1 ;
                bool flag = false ;
                int minnn = BFS(mapp[j].x,mapp[j].y,mapp[k].x,mapp[k].y) ;
                for(int h = 0 ; h < n ; h++)
                {
                    for(int l = 0 ; l < m ; l++)
                    {
                        if(ch[h][l] != '#') continue ;
                        if(!vis[h][l]){flag = true ; break ;}
                    }
                    if(flag) break ;
                }
                if(!flag) minn = min(minn,minnn) ;
            }
        }

        if(minn == INF) printf("-1
") ;
        else printf("%d
",minn) ;
    }
    return 0 ;
}
View Code

这个是ZP的,写的差不多,不过用时100多ms,所以贴出来瞻仰一下

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
using namespace std;
#define LL __int64
int map[11][11];
int num[11][11][11][11];
int vis[11][11];
int n,m;
struct list
{
    int x;
    int y;
    int t;
}p,q;
queue<struct list >que;
int xx[4]={1,-1,0,0};
int yy[4]={0,0,1,-1};
void dos(int i,int j,int a,int b,int t)
{
    while(!que.empty())que.pop();
    num[i][j][a][b]=0;
    p.x=a;
    p.y=b;
    p.t=0;
    que.push(p);
    vis[a][b]=1;
    while(!que.empty())
    {
        p=que.front();
        que.pop();
        num[i][j][p.x][p.y]=p.t;
        for(int i=0;i<4;i++)
        {
            q.x=p.x+xx[i];
            q.y=p.y+yy[i];
            q.t=p.t+1;
            if(q.x<1||q.x>n||q.y<1||q.y>m)continue;
            if(vis[q.x][q.y])continue;
            if(map[q.x][q.y]==0)continue;
            que.push(q);
            vis[q.x][q.y]=1;
        }
    }
}
char str[111];
int main()
{
    int T;
    int i,j,a,b,t,k;
    scanf("%d",&T);
    for(int _=1;_<=T;_++)
    {
        memset(map,0,sizeof(map));
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                for(k=1;k<=n;k++)
                {
                    for(t=1;t<=m;t++)
                    {
                        num[i][j][k][t]=999999;
                    }
                }
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%s",str);
            for(j=0;j<m;j++)
            {
                if(str[j]=='#')
                {
                    map[i][j+1]=1;
                }
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(map[i][j]==0)continue;
                memset(vis,0,sizeof(vis));
                dos(i,j,i,j,0);
            }
        }
        //cout<<num[2][1][2][1]<<endl;
        //cout<<num[2][3][2][3]<<endl;
        int minn=999999;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(map[i][j]==0)continue;
                for(a=1;a<=n;a++)
                {
                    for(b=1;b<=m;b++)
                    {
                        if(map[a][b]==0)continue;
                        int tt=0;
                        for(t=1;t<=n;t++)
                        {
                            for(k=1;k<=m;k++)
                            {
                                if(map[t][k]==0)continue;
                                tt=max(tt,min(num[i][j][t][k],num[a][b][t][k]));
                            }
                        }
                        minn=min(minn,tt);
                    }
                }
            }
        }
        printf("Case %d: ",_);
        if(minn==999999)
        {
            cout<<-1<<endl;
        }
        else cout<<minn<<endl;
    }
    return 0;
}
View Code

我还要贴一下会神的,因为限时1000ms,然后会神的代码就正好跑了1000ms。。。。。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 110
#define LL long long
#define INF 0xfffffff
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = ~0u>>2;
char s[12][12];
struct node
{
    int x,y;
    int num;
}p[N];
int vis[12][12],dis[4][2] = {0,1,0,-1,-1,0,1,0},n,m;
int judge(int x,int y)
{
    if(x<1||x>n||y<1||y>m) return 0;
    if(vis[x][y]) return 0;
    if(s[x][y]!='#') return 0;
    return 1;
}
int bfs(int x1,int y1,int x2,int y2)
{
    queue<node>q;
    node t1,t2;
    t1.num = 0;t1.x = x1,t1.y = y1;
    t2.num = 0;t2.x = x2,t2.y = y2;
    q.push(t1);
    q.push(t2);
    int mm=0;
    while(!q.empty())
    {
        t1 = q.front();q.pop();
        
        for(int i = 0 ;  i < 4 ;i++)
        {
            int tx = t1.x+dis[i][0];
            int ty = t1.y+dis[i][1];
            if(judge(tx,ty))
            {
                vis[tx][ty] = 1;
                t2.x = tx,t2.y = ty,t2.num = t1.num+1;
                q.push(t2);
            }
        }mm = max(mm,t1.num);
    }
    return mm;
}
int main()
{
    int t,i,j,kk=0,g;
    cin>>t;
    while(t--)
    {
        g = 0;
        cin>>n>>m;
        for(i = 1; i <= n; i++)
            for(j = 1; j <= m ;j++)
            {
                cin>>s[i][j];

                if(s[i][j]=='#')
                {
                    g++;
                    p[g].x = i;
                    p[g].y = j;
                }
            }
        int minz = INF;
        for(i = 1; i <= g ; i++)
            for(j = i ;j <=g ;j++)
            {
                memset(vis,0,sizeof(vis));
                vis[p[i].x][p[i].y] = 1;
                vis[p[j].x][p[j].y] = 1;
                int t1 = bfs(p[i].x,p[i].y,p[j].x,p[j].y);
                int flag = 0;
                for(int o = 1; o <= n;o++)
                    {
                        for(int e = 1; e <= m; e++)
                        if(s[o][e]=='#')
                        {
                            if(!vis[o][e])
                            {
                                flag = 1;
                                break;
                            }
                        }
                        if(flag) break;
                    }
                if(!flag)
                {
                    minz = min(minz,t1);
                }
            }
        printf("Case %d: ",++kk);
        if(minz!=INF)
        cout<<minz<<endl;
        else
        puts("-1");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/luyingfeng/p/3614447.html