模拟题卡到了现在><简直被自己蠢哭了。
直接用BFS模拟drop的运动状态。只有waterdrop meets drop才会合并,两个drop meet不会合并。且合并后waterdrop不会再运动,所以如果发生了合并,next节点不需再入队。
坑在了一个地方就是需要避免同一个位置crack多次的case,考虑一下这种case:
04A
0B0
其中4表示有一个size=4的waterdrop,坐标为(1,2);0表示空。在t时刻A、B处各有一个drop在向waterdrop运动。扩展B时,队列中会加入(1,2) size=5的节点C,之后再扩展A时,队列中会加入(1,2) size=6的节点D。那么t+1时刻C、D出队,(1,2)这一处就被crack了两次。避免这种case的方法,第一种是仅将合并后size==5时将next节点入队,size==5是第一次达到crack的标准。这样就避免了扩展多次重复的可以crack的节点。另一种是对每个入队的节点设一个bool Crack,如果出队的某个节点Crack==true而对应的mp[x][y]==0,就说明该位置之前已经cracked了,就可以忽略此次crack。
另外BFS返回时不能在time==T就return,需要continue,并且return前需要判断该节点会不会在T时刻crack。因为可能有多个节点会在T时刻crack,所以需要判断完所有的time==T的node。
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<ctype.h>
#include<map>
#include<time.h>
#include<bitset>
#include<set>
#include<list>
using namespace std;
//hdu 5336
const int maxn=110;
int T;
int r;
int c;
int n;
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
class node
{
public:
int x;
int y;
int dis;
int dir;
int idx;
bool crack;
public:
node()
{
x=0;
y=0;
dis=0;
dir=0;
idx=0;
crack=false;
}
};
node point[maxn];
int mp[maxn][maxn];
int subidx[maxn][maxn];
int mark[maxn];
int tim[maxn][maxn];
node st;
pair<int,int>ans[maxn];
void bfs()
{
queue<node>que;
node now=node();
st.dis=0;
st.idx=subidx[st.x][st.y];
st.crack=true;
que.push(st);
mp[st.x][st.y]=5;
while(!que.empty())
{
now=que.front();
que.pop();
if(now.dis==T) //the node "now" may be cracked at time T
{
// ans[now.idx]=make_pair(1,mp[now.x][now.y]);
// mark[now.idx]=true;
if(mp[now.x][now.y]>4)
{
tim[now.x][now.y]=now.dis;
mp[now.x][now.y]=0;
ans[now.idx]=make_pair(0,now.dis);
mark[now.idx]=true;
}
// return;
continue; //there could be more than one drop cracking at time T
}
//if(now.crack==true) //it's also ok then push the node into the queue only when mp[x0][y0]==5;
if(mp[now.x][now.y]>4)
{
if(subidx[now.x][now.y]!=0)//exclude the start point if it's not a drop
{
ans[now.idx]=make_pair(0,now.dis);
mark[now.idx]=true;
}
tim[now.x][now.y]=now.dis;
mp[now.x][now.y]=0;//crack
for(int i=0;i<4;i++)
{
int x0=now.x+dx[i];
int y0=now.y+dy[i];
if(x0<1||x0>r||y0<1||y0>c) continue;//||now.dis==T if there is no "continue" before, we need to add this condition or ||now.dis>=T
node next=node();
next.dis=now.dis+1;
next.x=x0;
next.y=y0;
next.dir=i;
next.idx=subidx[x0][y0];
next.crack=false;
if(mp[x0][y0])
{
mp[x0][y0]++;
if(mp[x0][y0]>4)
{
next.crack=true;
que.push(next);
}
}
else
{
que.push(next);
}
}
}
else
{
if(now.crack==true)
{
continue;
}
int x0=now.x+dx[now.dir];
int y0=now.y+dy[now.dir];
if(x0<1||x0>r||y0<1||y0>c) continue;//||now.dis==T
node next=node();
next.dis=now.dis+1;
next.x=x0;
next.y=y0;
next.dir=now.dir;
next.idx=subidx[x0][y0];
next.crack=false;
if(mp[x0][y0])
{
mp[x0][y0]++;
if(mp[x0][y0]>4)
{
next.crack=true;
que.push(next);
}
}
else
{
que.push(next);
}
}
}
}
int main()
{
freopen("input.txt","r",stdin);
while(scanf("%d %d %d %d",&r,&c,&n,&T)!=EOF)
{
memset(mp,0,sizeof(mp));
memset(subidx,0,sizeof(subidx));
memset(point,0,sizeof(point));
memset(mark,false,sizeof(mark));
memset(ans,0,sizeof(ans));
memset(tim,0,sizeof(tim));
for(int i=1;i<=n;i++)
{
int x=0;
int y=0;
int sz=0;
scanf("%d %d %d",&x,&y,&sz);
point[i].x=x;
point[i].y=y;
mp[x][y]=sz;
point[i].idx=i;
subidx[x][y]=i;
}
scanf("%d %d",&st.x,&st.y);
bfs();
for(int i=1;i<=n;i++)
{
// if(mp[point[i].x][point[i].y])
// {
// printf("1 %d\n",mp[point[i].x][point[i].y]);
// }
// else
// {
// printf("0 %d\n",tim[point[i].x][point[i].y]);
// }
if(mark[i]==true)
{
printf("%d %d\n",ans[i].first,ans[i].second);
}
else
{
printf("1 %d\n",mp[point[i].x][point[i].y]);
}
}
}
return 0;
}