codeforces1105D-暴力BFS

D. Kilani and the Game

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Kilani is playing a game with his friends. This game can be represented as a grid of size n×m

, where each cell is either empty or blocked, and every player has one or more castles in some cells (there are no two castles in one cell).

扫描二维码关注公众号,回复: 9513843 查看本文章

The game is played in rounds. In each round players expand turn by turn: firstly, the first player expands, then the second player expands and so on. The expansion happens as follows: for each castle the player owns now, he tries to expand into the empty cells nearby. The player i

can expand from a cell with his castle to the empty cell if it's possible to reach it in at most si (where si

is player's expansion speed) moves to the left, up, right or down without going through blocked cells or cells occupied by some other player's castle. The player examines the set of cells he can expand to and builds a castle in each of them at once. The turned is passed to the next player after that.

The game ends when no player can make a move. You are given the game field and speed of the expansion for each player. Kilani wants to know for each player how many cells he will control (have a castle their) after the game ends.

Input

The first line contains three integers n

, m and p (1≤n,m≤1000, 1≤p≤9

) — the size of the grid and the number of players.

The second line contains p

integers si (1≤s≤109

) — the speed of the expansion for every player.

The following n

lines describe the game grid. Each of them consists of m symbols, where '.' denotes an empty cell, '#' denotes a blocked cell and digit x (1≤x≤p) denotes the castle owned by player x

.

It is guaranteed, that each player has at least one castle on the grid.

Output

Print p

integers — the number of cells controlled by each player after the game ends.

Examples

Input

Copy

3 3 2
1 1
1..
...
..2

Output

Copy

6 3 

Input

Copy

3 4 4
1 1 1 1
....
#...
1234

Output

Copy

1 4 3 3 

Note

The picture below show the game before it started, the game after the first round and game after the second round in the first example:

In the second example, the first player is "blocked" so he will not capture new cells for the entire game. All other player will expand up during the first two rounds and in the third round only the second player will move to the left.

题意:一个图,一群人,每个人有自己的速度。按顺序来占领空格子,有#的是墙。输出每个人占领的格子数量。速度的意思是从起点出发走一个格子需要1速度,走可以拐弯。轮到的时候占领的格子==自己随意走能到的格子之和

样例:

4 4 2

2 4

。。。。

。。。。

1。。。

。。#2

顺序来:   1的起点是[3][1],可以上右,上上,右右,右下,下,所以1占领的格子有7,加上起点是8个。2的起点是[4][4],可以上上上左,上上左,左边有墙不能走,2占领的格子是5个,加上起点是6个。然后这样顺序扩散,直到所有格子占领完。

之后输出是:   9 6

思路:一开始没看清题意wa了几发,之后我用双bfs做一下发现出问题了,后面我去看了一下大佬的代码。。。就是不一样,用的暴力bfs

坑点:起点不止一个,比如可以这样

3 3 2

1 1

111

。。。

222

AC代码:

#include<cstdio>
#include<queue>
#include <iostream>
#include <cstring>
using namespace std;
int n,m,p;
const int maxn=1000+10;
char map[maxn][maxn];
int vis[maxn][maxn],sp[10];
long long int ans[10];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
struct Node
{
	int x,y,i;
};
queue<Node> q[10],qu;
bool judge(int x,int y)
{
	if (x<0||y<0||x>=n||y>=m||vis[x][y]!=0||map[x][y]=='#')
		return true;
	return false;
}
int bfs(int start)
{
	int i,sum;
	Node now,end;
//	cout<<start<<"--------"<<endl;
	sum=q[start].size();
	for (i=0;i<sum;i++)           //把队列组里面的数据放进新的队列里面
		{
			qu.push(q[start].front());
			q[start].pop();
		}
	while (!qu.empty())
		{
			now=qu.front();
			qu.pop();
			for (i=0;i<4;i++)
				{
					end.x=now.x+dir[i][0];
					end.y=now.y+dir[i][1];
					end.i=now.i;
					if (judge(end.x,end.y)==true)
						continue;
					vis[end.x][end.y]=end.i;
					q[start].push(end);               //把扩散的点放进队列组里面,方便下一次扩散
			//		cout<<end.x<<"-"<<end.y<<" "<<end.i<<endl;
				}
		}
	return q[start].size();
}
int main()
{
	Node now;
	int i,j,k;
	cin>>n>>m>>p;
	memset(sp,0,sizeof(sp));
	memset(vis,0,sizeof(vis));
	for (i=1;i<=p;i++)
		{
			scanf("%d",&sp[i]);
			if (sp[i]>1000)
				sp[i]=1000;
		}
	for (i=0;i<n;i++)
		scanf("%s",map[i]);
	for (i=0;i<n;i++)
		for (j=0;j<m;j++)                
			if (map[i][j]>'0'&&map[i][j]<='9')
				{
					vis[i][j]=map[i][j]-'0';
					now.x=i;now.y=j;now.i=vis[i][j];
					q[now.i].push(now);                 //我们把各个起点放在队列组里面
			//		cout<<i<<" - "<<j<<endl;
				}
	bool ch;
	while (true)
		{
			ch=false;
			for (i=1;i<=p;i++)
				for (j=1;j<=sp[i];j++)        //这里循环一个速度可以看成扩散多少次
					if (bfs(i)!=0)          //如果能扩散,就继续
						ch=true;
					else break;           //不能就跳过这个人
			if (ch==false)                    //如果都不能扩散,退出
				break;
		}
	for (i=0;i<n;i++)
		for (j=0;j<m;j++)
			{
				ans[vis[i][j]]++;
	//			cout<<vis[i][j]<<" ";
	//			if (j==m-1) cout<<endl;
			}
	for (i=1;i<=p;i++)
		if (i==p) cout<<ans[i]<<endl;
		else cout<<ans[i]<<" ";
	return 0;
}
发布了46 篇原创文章 · 获赞 2 · 访问量 3215

猜你喜欢

转载自blog.csdn.net/z1164754004z/article/details/86572759