Goblin Wars
Time Limit:432MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Description
The wizards and witches of Hogwarts School of Witchcraft found Prof. Binn's History of Magic lesson to be no less boring than you found your own history classes. Recently Binns has been droning on about Goblin wars, and which goblin civilization fought which group of centaurs where etc etc. The students of Hogwarts decided to use the new-fangled computer to figure out the outcome of all these wars instead of memorizing the results for their upcoming exams. Can you help them?
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
题解:
很显然是广度优先,使用tag[i][j]记录被占领的时间,无主地初始化为0,一开始的部落初始化为1,以后记录每块地被占领的时间。先将原始部落入队,然后再占领其他的地。
情况比较多,仔细考虑,应该没有什么问题。
以下是代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#
include
<cstdio>
#
include
<string>
#
include
<cstring>
#
include
<cstdlib>
#
include
<cmath>
#
include
<iostream>
#
include
<algorithm>
#
include
<queue>
#
include
<cctype>
using
namespace
std;
#define ss(x) scanf(
"%d"
,&x)
#define ff(i,s,e)
for
(
int
i=s;i<e;i++)
#define fe(i,s,e)
for
(
int
i=s;i<=e;i++)
#define print(x) printf(
"%d\n"
,x);
#define write() freopen(
"1.in"
,
"r"
,stdin);
struct Node{
int
x, y,k;
char a;
void
set ( int i, int j){
x=i;y=j;
}
}t,tp;
const
int N = 600 ;
const
int xx[ 4 ]={ 0 , 0 ,- 1 , 1 }; //代表四个方向
const
int yy[ 4 ]={ 1 ,- 1 , 0 , 0 };
char str[N][N];
int
r,c;
int
tag[N][N];
void
solve(){
memset(tag,
0
,sizeof(tag));
queue<Node>q;
int
x,y;
ff(i,
0
,r)
ff(j,
0
,c)
//先将最先的部落入队
if
(isalpha(str[i][j])){
t.
set
(i,j);
tag[i][j]=
1
;
q.push(t);
}
while
(!q.empty()){
tp=q.front();
q.pop();
int
_x=tp.x,_y=tp.y;
char pre = str[_x][_y];
if
(str[_x][_y]==
'*'
)
continue
;
//已经爆发战争,继续
ff(i,
0
,
4
){
//向四个方向前进
x=tp.x+xx[i];
y=tp.y+yy[i];
char ch = str[x][y];
if
(ch == pre)
continue
;
//如果是自己部落,继续
if
(x<
0
|| x >=r || y< 0 || y>=c) continue ; //越界,继续
if
(ch==
'#'
|| ch==
'*'
)
continue
;
//不能居住,继续
if
(ch==
'.'
){
//可以占领,占领后入队
t.
set
(x,y);
str[x][y]=pre;
tag[x][y]=tag[_x][_y]+
1
;
q.push(t);
}
else
if (tag[_x][_y]+ 1 != tag[x][y]) continue ; //不是同时占领的,继续
else
str[x][y]= '*' ; //同时占领的不同部落爆发战争
}
}
}
int
main(){
//
write();
int
T;
ss(T);
while
(T--){
ss(r);ss(c);
ff(i,
0
,r)
scanf(
"%s"
,str[i]);
solve();
ff(i,
0
,r)
puts(str[i]);
printf(
"\n"
);
}
}
|