bfs

题目链接:https://vjudge.net/contest/237052#problem/J

 

The magical world looks like a 2-D R*C grid. Initially there are many civilizations, each civilization occupying exactly one cell. A civilization is denoted by a lowercase letter in the grid. There are also certain cells that are uninhabitable (swamps, mountains, sinkholes etc.) - these cells are denoted by a '#' in the grid. All the other cells - to which the civilizations can move  - are represented by a '.' in the grid.

 

A cell is said to be adjacent to another cell if they share the same edge - in other words, for a cell (x,y), cells (x-1, y), (x, y-1), (x+1, y), (x, y+1) are adjacent, provided they are within the boundaries of the grid.   Every year each civilization will expand to all unoccupied adjacent cells. If it is already inhabited by some other civilization, it just leaves the cell alone. It is possible that two or more civilizations may move into an unoccupied cell at the same time - this will lead to a battle between the civilizations and the cell will be marked with a '*'. Note that the civilizations fighting in a particular cell do not try to expand from that cell, but will continue to expand from other cells, if possible.

Given the initial grid, output the final state of the grid after no further expansion by any civilization is possible.

 

Input (STDIN):

The first line contains T, the number of cases. This is followed by T test case blocks.

Each test case contains two integers, R, C.

This is followed by R lines containing a string of length C. The j-th letter in the i-th row describes the state of the cell in year 0.

Each cell is either a

1. '.' which represents an unoccupied cell

2. '#' which represents a cell that cannot be occupied

3. A civilization represented by a lowercase letter ('a' - 'z')

 

Output (STDOUT):

For each test case, print the final grid after no expansion is possible. Apart from the notations used in the input, use '*' to denote that a battle is being waged in that particular cell. 

Print a blank line at the end of each case.

 

Constraints:

1 <= R, C <= 500

1 <= T <= 5

 

Sample Input:

5

3 5

#####

a...b

#####

3 4

####

a..b

####

3 3

#c#

a.b

#d#

3 3

#c#

...

a.b

3 5

.....

.#.#.

a...b

 

Sample Output:

#####

aa*bb

#####

 

####

aabb

####

 

#c#

a*b

#d#

 

#c#

acb

a*b

 

aa*bb

a#.#b

aa*bb

 

 题目大意:输入t,t组数据,输入n,m;   n行m列,输入字符,如果字符是a~z,就是一个部落,如果是‘.',则是可以被'a~z'的部落占领的块,如果是'#',则不能被占领,每个部落向外

扩展一个点需要一年,只能往左往右往上往下,如果两个部落在同一时间到达'.',则设置为'*',并且不能走这条路了,输出最后结果

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<set>
#include<queue>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
#define INF 0x3f3f3f
int n,m;
char a[510][510];
bool vis[510][510];
int time1[510][510];//代表该点被到达的时间,INF为没有到达
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
struct Qu
{
    int time,x,y;//代表到达该点的时间,该点坐标
    char c;//该点字符
};
queue<Qu>p;//申请一个队列
void bfs()
{
    while(!p.empty())
    {
        Qu q=p.front();//取队头元素
        p.pop();//队头元素出队
        if(a[q.x][q.y]=='*')
            continue;
        for(int i=0;i<4;i++)
        {
            Qu s1=q;
            s1.time=q.time+1;
            s1.x=q.x+dx[i];
            s1.y=q.y+dy[i];
            if(s1.x>=0&&s1.x<n&&s1.y>=0&&s1.y<m&&time1[s1.x][s1.y]==INF&&a[s1.x][s1.y]=='.')
            {
                a[s1.x][s1.y]=s1.c;
                time1[s1.x][s1.y]=s1.time;
                p.push(s1);

            }
            else if(s1.x>=0&&s1.x<n&&s1.y>=0&&s1.y<m&&s1.time==time1[s1.x][s1.y]&&a[s1.x][s1.y]!=s1.c)
            {
                a[s1.x][s1.y]='*';
            }
        }

    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        //memset(vis,false,sizeof(vis));
        //在该点是否有部落
        cin>>n>>m;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                time1[i][j]=INF;
        }
        while(!p.empty())
            p.pop();//使得队列为空
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                cin>>a[i][j];
                if(a[i][j]!='.'&&a[i][j]!='#')
                {
                    Qu s;
                    s.x=i;
                    s.y=j;
                    s.c=a[i][j];
                    s.time=0;
                    p.push(s);
                    time1[i][j]=0;
                }
            }
        }
        bfs();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                cout<<a[i][j];
            cout<<endl;
        }
        cout<<endl;
    }
    return 0;
}

 

题目链接:https://vjudge.net/contest/238680#problem

Statements

Vitaly works at the warehouse. The warehouse can be represented as a grid of n × m cells, each of which either is free or is occupied by a container. From every free cell it's possible to reach every other free cell by moving only through the cells sharing a side. Besides that, there are two robots in the warehouse. The robots are located in different free cells.

Vitaly wants to swap the robots. Robots can move only through free cells sharing a side, moreover, they can't be in the same cell at the same time or move through each other. Find out if the swap can be done.

Input

The first line contains two positive integers n and m (2 ≤ n·m ≤ 200000) — the sizes of the warehouse.

Each of the next n lines contains m characters. The j-th character of the i-th line is «.» if the corresponding cell is free, «#» if there is a container on it, «1» if it's occupied by the first robot, and «2» if it's occupied by the second robot. The characters «1» and «2» appear exactly once in these lines.

Output

Output «YES» (without quotes) if the robots can be swapped, and «NO» (without quotes) if that can't be done.

Examples
Input
5 3

###

#1#

#.#

#2#

###
Output
NO
Input
3 5

#...#

#1.2#

#####
Output
YES


题目大意,n行m列,但是注意数据范围1<=n*m<=200000,用二维数组会爆,所以只能用一维存二维。如果输入的是'#',则不能走,其他的可以走,要求1 2实现交换
具体思路看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<set>
#include<queue>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=2e5+10;
const ll maxa=32050;
#define INF 0x3f3f3f3f3f3f
//1和2能交换无外乎两种情况,一种就是有两条路以上,还有就是至少有一条路,但是同时在路上有一个点有三个地方可走
char a[maxn];//题目中数据范围是n*m<=2e5,但是直接开二维会爆,所以只能用一维来存储
int n,m,flag=0;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
bool vis[maxn];
struct Qu
{
    int x,y;
};
queue<Qu>p;//申请一个队列
void bfs(int xx,int yy)
{
    while(!p.empty())
    p.pop();//使得队列为空
    int sum=0;
    Qu s1,s2,s3;
    s1.x=xx;
    s1.y=yy;
    p.push(s1);
    vis[s1.x*m+s1.y]=true;//如果入队了就标记,不然的话就一直在一个点重复遍历了
    while(!p.empty())
    {
        sum=0;
        s2=p.front();//取走队头元素,同时出队
        p.pop();
        for(int i=0;i<4;i++)
        {
            int x1=s2.x+dx[i];//遍历四个方向
            int y1=s2.y+dy[i];
            if(x1>=0&&x1<n&&y1>=0&&y1<m&&a[x1*m+y1]!='#')
            {
                sum++;//可以走的一个地方,sum++记录有多少个可以走的地方
                s3.x=x1;
                s3.y=y1;
                if(!vis[x1*m+y1])
                {
                    vis[x1*m+y1]=true;//如果未被入队,则入队,同时标记
                    p.push(s3);
                }

            }
        }
        if(sum>=3)
            flag=1;
    }
}
int main()
{
    memset(vis,false,sizeof(vis));
    cin>>n>>m;
    int x1,y1,x2,y2,ans=0,sum=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>a[i*m+j];
            if(a[i*m+j]=='1')
            {
                x1=i;
                y1=j;
            }
            else if(a[i*m+j]=='2')
            {
                x2=i;
                y2=j;
            }
        }
    }
    for(int i=0;i<4;i++)
    {
        memset(vis,false,sizeof(vis));
        int x3=x1+dx[i];
        int y3=y1+dy[i];
        if(x3>=0&&x3<n&&y3>=0&&y3<m&&a[x3*m+y3]!='#')
        {
            sum++;
            vis[x1*m+y1]=true;
            bfs(x3,y3);
        }
        if(vis[x2*m+y2])
            ans++;
    }
    if(sum>=3)
        flag=1;
    if(ans>=2||(ans>=1&&flag))
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;
    return 0;
}

 

posted @ 2018-07-14 16:37  执||念  阅读(173)  评论(0编辑  收藏  举报