ZSTUOJ 4215 Landlocked

4215: Landlocked

Time Limit: 5 Sec   Memory Limit: 128 MB
Submit: 276   Solved: 35

Description

Canada is not a landlocked country: the country touches at least one ocean (in fact, it touches three).

There are 46 countries (including Bolivia and Mongolia, for example) which are landlocked. That is, they do not touch an ocean, but by going through one other country, an ocean can be reached. For example, a person in Mongolia can get to an ocean by passing through Russia.

Liechtenstein and Uzbekistan are the only two countries in the world which are land-landlocked. That is, not only are they land-locked, but all countries which surround these two countries are land-locked countries. Thus, one would have to pass through at least two different countries when leaving Uzbekistan before arriving at an ocean.

Your task is to determine how landlocked each country is on a given map. We say that a country is not landlocked (recorded as 0) if it touches water in any adjacent cell in either a horizontal, vertical, or diagonal direction. If a country is landlocked, you must calculate the minimum number of borders that one must cross in order to travel from the country to water. Each step of such a journey must be to a cell that is adjacent in either a horizontal, vertical, or diagonal direction. Crossing a border is defined as taking a step from a cell in one country to an adjacent cell in a different country.

Note that countries may not be connected to themselves (as in a country formed of islands). In this case, the landlocked value for the country is the minimal of each connected region of the country.

Input

The first line contains N and M (1 ≤ N, M ≤ 1000).

On each of the next N lines, there are M capital letters. Each country will be represented by a unique letter, with the exception that the letter W is reserved to indicate the water in the oceans or seas that will be used to determine the how landlocked each country is.

Output

The output consists of the country letter followed by a space, followed by the landlockedness for that particular country. Output should be in alphabetical order

Sample Input

7 10 
WWWWWCCDEW
WWWWCCEEEW
WTWWWCCCCW
WWFFFFFFWW
WWFAAAAFWW
WWFABCAFFW
WWFAAAAFWW

Sample Output

A 1
B 2
C 0
D 1
E 0
F 0
T 0

HINT

题意:给出一个图你,让你判断每一个国家到海的距离,一个格子为一个单位距离。搜索的时候要从上下左右+对角线,这8个方向搜索。

思路:看了题解之后理解的,一开始觉得有难度,但是把案例画出来之后就简单了。就是假设存在一个图如下

蓝色的是海,其他的为国家地界,每个国家的颜色不同,看到图就知道要用BFS了。首先从海开始搜,并标记为海的格子为-1.然后搜第二层,并标记为0,第三层标记为1,以此类推。最后就得出了每个点到海的距离了,然后选取最小值就行了。代码和题解的差不多,贴上。
#include<bits/stdc++.h>
using namespace std;
#define maxn 1005
char ma[maxn][maxn];
int vis[maxn][maxn];
int d[maxn][maxn];
int dd[30];
int dir[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
int n,m;
queue<int>q[10];
int ok(int x,int y)
{
    if(x<0||y<0||x>=n||y>=m||vis[x][y]==1)
        return 0;
    return 1;
}
void dfs(int x,int y,char ch,int val,int p)
{
    vis[x][y]=1;
    d[x][y]=val;
    for(int i=0; i<8; i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        if(ok(tx,ty)==0)
            continue;
        if(ma[tx][ty]!=ch)
        {
            q[p].push(tx);
            q[p].push(ty);
            q[p].push(val+1);
        }
        else
        {
            dfs(tx,ty,ch,val,p);
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        memset(d,-1,sizeof(d));
        memset(dd,0x3f3f3f3f,sizeof(dd));
        for(int i=0; i<n; i++)
        {
            scanf("%s",ma[i]);
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(ma[i][j]=='W')
                {
                    q[0].push(i);
                    q[0].push(j);
                    q[0].push(-1);
                }
            }
        }
        for(int i=0; !q[i].empty(); i++)
        {
            while(!q[i].empty())
            {
                int x=q[i].front();
                q[i].pop();
                int y=q[i].front();
                q[i].pop();
                int val=q[i].front();
                q[i].pop();
                if(vis[x][y]==1)
                    continue;
                dfs(x,y,ma[x][y],val,i);
            }
        }
        /*for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
               printf("%d ",d[i][j]);
            }
            printf("\n");
        }*/

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                dd[ma[i][j]-'A']=min(dd[ma[i][j]-'A'],d[i][j]);
            }
        }
        for(int i=0;i<30;i++)
        {
            if(dd[i]==0x3f3f3f3f)
                continue;
            if('W'-'A'==i)
                continue;
            printf("%c %d\n",i+'A',dd[i]);
        }
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值