样例输入1
2 2 2
2 0
0 0
1
1 1
样例输出1
YES
样例输入2
2 2 2
2 0
0 0
2
1 2
1 1
样例输出2
NO
0 2
0 0
代码:
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define Bug cout << "---------------------" << endl
using namespace std;
const int N = 100;
int arr[N][N];
bool tm[N][N];//每个位置水滴的破开时间
int n, m, l;
int x, y;
int dir[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };
struct Node {
int x, y;
int pos;//表示方向;
int time;
};
bool in(int x, int y) {
return x >= 0 && x < n&& y >= 0 && y < m;
}
void bfs() {
memset(tm, -1, sizeof(tm));
Node now, next;
queue<Node>q;
//对于每个破掉的水滴才需要bfs,所以需要先判断是否破裂;
arr[x][y]++;
if (arr[x][y] > l) {//破裂后要将此状态放入到队列中执行BFS;
for (int i = 0;i < 4;i++) {
now.x = x;
now.y = y;
now.pos = i;//四个方向,一个水滴破裂成4个;
now.time = 0;//第一个破裂,以此为起始,则为0
q.push(now);
}
arr[x][y] = 0;
tm[x][y] = 0;
//破裂后状态归0;
}
//进行bfs
while (!q.empty()) {
now = q.front();
q.pop();
//每个水滴破裂成四个水滴,且四个水滴已经存入到状态中,所以对于每个状态的方向进行bfs;
int tx = now.x + dir[now.pos][0];//即需要访问的下一个位置是当前位置加上方向;
int ty = now.y + dir[now.pos][1];
if (in(tx, ty)) {
if (now.time + 1 == tm[tx][ty]) {
//如果一秒内多个水滴进入同一个格子;即破裂后的水滴遇到了水滴,那个水滴破裂后也进入到了同一个网格
continue;
}
else if (arr[tx][ty]!=0) {//如果该地方水滴不为0;
arr[tx][ty]++;
//如果加上之后破裂了,则把破裂的水滴放入状态中去;
if (arr[tx][ty] > l) {
for (int i = 0;i < 4;i++) {
next.x = tx;
next.y = ty;
next.pos = i;
next.time = now.time + 1;
q.push(next);
}
arr[tx][ty] = 0;
tm[tx][ty] = now.time + 1;
}
}
else {//该位置没水滴,水滴会继续飞,飞向下一个点,
next.x = tx;
next.y = ty;
next.pos = now.pos;//方向是确定的,下次会继续叠加;
next.time = now.time + 1;
q.push(next);
}
}
}
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m >> l;
for (int i = 0;i < n;i++) {
for (int j = 0;j < m;j++) {
cin >> arr[i][j];
}
}
int q;
cin >> q;
while (q--) {
cin >> x >> y;
x--;
y--;
bfs();
}
bool flag = true;
for (int i = 0;i < n;i++) {
for (int j = 0;j < m;j++) {
if (arr[i][j] != 0) {
flag = false;
}
}
}
if (flag) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
for (int i = 0;i < n;i++) {
for (int j = 0;j < m;j++) {
cout << arr[i][j] << ' ';
}
cout << endl;
}
}
}