題目鏈接HDU 5336
題意大概就是類似於十滴水遊戲,一開始會從(x,y)點擴散出4個方向的小水珠,題目也會給你一些大水珠,每個大水珠都有他自己目前的水滴數,如果
某個大水珠的水滴數大過4,就會爆掉,並同時向四個方向發射出小水珠,小水珠每秒移動一格,題目問T秒後原本各個大水珠的狀態。這題其實模擬很簡單的,但是有個地方坑,就是如果一個小水珠觸發爆了某個大水珠,那麼此時也剛好到達這個大水珠的小水珠也會消失,相當於多個小水珠同時到達一個大水珠,大水珠爆了,所有此時在這裏的小水珠都沒有了,不然會多小水珠的。
代碼
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
const int dx[] = {0,0,1,-1};
const int dy[] = {1,-1,0,0};
int drops[110][110][2];//最後一維0表示本來的水珠,1表示什麼時候爆了
int n,m,sx,sy,t,kase;
struct po
{
int x,y;
};
po ans[110];//記錄出答案的順序
struct drop//模擬小水珠
{
int x,y,st,dir;
};
void bfs()
{
queue<drop> q;
drop an = {sx,sy,0,0};
q.push(an);
an.dir++;
q.push(an);
an.dir++;
q.push(an);
an.dir++;
q.push(an);//四個方向很簡單
while(!q.empty())
{
drop v = q.front();
q.pop();
if(v.st >= t) continue;
int xn = v.x + dx[v.dir];
int yn = v.y + dy[v.dir];
if(xn <= 0 || yn <= 0 || xn > n || yn > m) continue;//如果小水珠越過地圖,自然會被抵消
if(drops[xn][yn][1] == v.st+1) continue; //這裏非常坑,就是一個小水珠弄爆了一個大水珠的話,其他同時過來的水珠都會被抵消掉,不然就會多出小水珠來
if(drops[xn][yn][0] != 0 ){
if(drops[xn][yn][0] >= 4){
drops[xn][yn][1] = v.st+1;
drops[xn][yn][0] = 0;
drop u = {xn,yn,v.st+1,0};
q.push(u);
u.dir++;
q.push(u);
u.dir++;
q.push(u);
u.dir++;
q.push(u);
}
else if(drops[xn][yn][0]<4) drops[xn][yn][0]++;
}else {
drop u = {xn,yn,v.st+1,v.dir};
q.push(u);
}
}
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&kase,&t))
{
int x,y,sizee;
memset(drops,0,sizeof(drops));
for(int i=0; i<kase; i++)
{
scanf("%d%d%d",&x,&y,&sizee);
drops[x][y][0] = sizee;
ans[i].x = x;
ans[i].y = y;
}
scanf("%d%d",&sx,&sy);
bfs();
for(int i=0;i<kase;i++){
if(drops[ans[i].x][ans[i].y][1]){
printf("0 %d\n",drops[ans[i].x][ans[i].y][1]);
}else printf("1 %d\n",drops[ans[i].x][ans[i].y][0]);
}
}
return 0;
}