G - YY's Minions
Time Limit:2000MS MemoryLimit:65536KB 64bit IO Format:%lld& %llu
Description
DespiteYY's so much homework, she would like to take some time to play with herminions first.
YY linesher minions up to an N*M matrix.Every minion has two statuses: awake or asleep. We use 0(the digit) torepresent that it is asleep, and 1 for awake. Also, we define the minions whoare around a minion closest in one of the eight directionsits neighbors. And every minute every minion will change its status by thefollowing specific rules:
· If this minion is awake, and the number ofits neighbors who are awake is less than 2, this minion will feel lonely andturn to asleep.
· If this minion is awake, and the number ofits neighbors who are awake is more than 3, this minion will turn to asleep forit will feel too crowded.
· If this minion is awake, and the number ofits neighbors who are awake is exactly 2 or 3, this minion will keep being awake and feel very happy.
· If this minion is asleep, and the number ofits neighbors who are awake is exactly 3, this minion will wake up because ofthe noise.Note that all changes take place at the same time at the beginning ofa specific minute.
Also,some minions will get bored and leave this silly game. We use 'X's to describethem. We suppose that a minion would leave after Tminutes. It will leave at the end of the Tth minute. Its status is considered during thechange at the beginning of the Tth minute, and should be ignored after that. Of course, oneminion will not leave twice!
YY is agirl full of curiosity and wants to know every minion's status after F minutes. But youknow she is weak and lazy! Please help this cute girl to solve this problem :)
Input
Thereare multiple test cases.
Thefirst line contains the number of test cases Q. 1<=Q<=100.
For each case, there are several lines:
The first line contains four integers N, M, F, K. K means the number ofleaving messages. 1<=N, M<=50, 1<=F<=1000, 1<=K<=N*M.
Next N linesare the matrix which shows the initial status of each minion. Each line contains M chars. We guaranteethat 'X' wouldn't appear in initial status matrix.
And next K linesare the leaving messages. Each line contains three integers Ti, Xi, Yi, They mean theminion who is located in (Xi, Yi) will leave thegame at the end of the Tith minutes. 1<=Ti<= F, 1<=Xi<=N, 1<=Yi<=M.
Output
For eachcase, output N lines asa matrix which shows the status of each minion after F minutes.
Sample Input
2
3 3 2 1
101
110
001
1 2 2
5 5 6 3
10111
01000
00000
01100
10000
2 3 3
2 4 1
5 1 5
Sample Output
010
1X0
010
0000X
11000
00X00
X0000
00000
Hint
For case 1:
T=0, the gamestarts
101
110
001
---------------
at the beginning ofT=1, a change took place
100
101
010
---------------
at the end of T=1(the minion in (2,2) left)
100
1X1
010
---------------
at the beginning ofT=2, a change took place
010
1X0
010
---------------
at the end of T=2(nothing changed for no minion left at T=2)
010
1X0
010
题目大意:有一个N*M 的矩阵,上面的每一个点每过一秒就会根据他八个方向的点的状态变化一次,变化的规则如下:
若一个点的状态为‘1’,且他八个方向上的‘1’的个数少于2或者大于3,那么这个点的状态变为‘0’,否则保持不变;
若一个点的状态为‘0’,且他八个方向上的‘1’的个数正好为3,那么这个点的状态变为‘1’;
若有一个点离开,则这个点的状态变为‘X'。
注意:所有点的变化都是在同一时刻发生的,不管用什么方式遍历,都要注意不能直接在原始数据上改动,应该把最后改动完成的结果反馈到原始数据。
上代码:
#include <iostream>
#include <memory.h>
using namespace std;
struct LEAVE//定义一个结构体,因为离开信息有三个,x,y和离开时间,而且还不止一个离开,所以需要一个结构体数组来保存离开信息
{
int t,x,y;
} leave[3000];
char b[100][100];//临时数组,根据原始数组每一个点周围的状态来确定本数组相应点的状态
char a[100][100];//原始数组,用来存储每一秒钟之后变化的最终结果
void p(int x,int y,int length,int ti) //状态转换函数,x,y为数组的边界,length为离开数组的长度,ti为当前时间
{
int i,j;
for(i=1; i<=x; i++)//双重循环用来遍历整个二维数组
for(j=1; j<=y; j++)
{
int sum=0;
if(a[i-1][j-1]!='X')//以下每一步都是先检测某个点周围的点是不是'X',如果不是,就把这个点的字符所代表的数值减去48加到sum中去,从而
sum+=(int)a[i-1][j-1]-48;//从而获得正确的数值,判断最后的结果和2,3的关系
if(a[i-1][j]!='X')
sum+=(int)a[i-1][j]-48;
if(a[i][j-1]!='X')
sum+=(int)a[i][j-1]-48;
if(a[i+1][j+1]!='X')
sum+=(int)a[i+1][j+1]-48;
if(a[i][j+1]!='X')
sum+=(int)a[i][j+1]-48;
if(a[i+1][j]!='X')
sum+=(int)a[i+1][j]-48;
if(a[i-1][j+1]!='X')
sum+=(int)a[i-1][j+1]-48;
if(a[i+1][j-1]!='X')
sum+=(int)a[i+1][j-1]-48;
if(a[i][j]=='1')//如果这个点的状态为‘1’
{
if(sum<2||sum>3)//并且周围为’1‘的点的个数小于2个或者大于3个
b[i][j]='0';//改点的状态变为’0‘
else
b[i][j]='1';//否则,这个点的状态就是’1‘
}
if(a[i][j]=='0')//如果这个点的状态为’0‘<pre name="code" class="cpp" style="color: rgb(51, 51, 51);">
{ if(sum==3)//并且这个点周围为’1‘的点的个数为3 b[i][j]='1';//这个点的状态变为’1‘elseb[i][j]='0';//否则这个点的状态就是’0‘ }//cout<<"sum "<<sum<<endl; } for(i=0;i<length;i++)//最后还要对离开的点进行处理,就是遍历一遍离开数组,看在这个时刻有没有离开的,有的话,就把状态变为’X‘
if(leave[i].t==ti)
{//cout<<"Hello"<<endl;
b[leave[i].x][leave[i].y]='X';
}
for(i=1;i<=x;i++)
for(j=1;j<=y;j++)
a[i][j]=b[i][j];
}
int main()
{
int t;
cin>>t;
while(t--)
{
int x,y,time,l;
int i,j;
cin>>x>>y>>time>>l;//输入x,y坐标,经过的时间的长度,以及离开的人数,即离开数组的长度
for(i=0; i<100; i++)//初始化一下原始数据数组
memset(a[i],'0',sizeof(a[i]));
for(i=1; i<=x; i++)//输入原始数据
for(j=1; j<=y; j++)
{
cin>>a[i][j];
}
for(i=0; i<l; i++)//输入离开数组的信息
cin>>leave[i].t>>leave[i].x>>leave[i].y;
for(i=1; i<=time; i++)//i代表当前的时刻,每一个时刻都要变化一次
p(x,y,l,i);
/*for(i=0;i<l;i++)
a[leave[i].x][leave[i].y]='X';*/
for(i=1; i<=x; i++)//最后,输出变化后的原始数组
{
for(j=1; j<=y; j++)
{cout<<a[i][j];
}
cout<<endl;
}
}
return 0;
}
/*
2
5 5 6 3
10111
01000
00000
01100
10000
2 3 3
2 4 1
5 1 5
*/