标签:
题意:
在一个 r*c 的格子图上,有 n 个水滴静止。每当水滴体积超过 4 时,会分成 4 个体积为 1 的小水滴向上下左右四个方向运动,每秒移动一个格子。小水滴与静止的水滴碰撞后会合成,体积相加。开始时 n 个水滴都静止,给出一个在 (x,y) 位置炸开的水滴作为启动源。
注意:1.小水滴彼此间不影响,即使同时经过同一位置。
2.若多个小水滴同时到达同一格子,则都与位于该格子的水滴合体,体积相加。超过 4 后按上述规则分裂。(即使为6,7等等)
思路:
因为数据较小所以直接暴力模拟O(nT)也能过。。
笔者用优先队列维护最先受到影响的水滴,依次处理,直到时间超出 T 或者是优先队列为空,则终止。
刚开始没有注意到应该注意的两点各种跪。。
水滴的结构体中还有一个变量 dir 记录该影响移动的方向。因为存在到了该“影响”发生的时候原有位置的水滴已经分裂不存在的情况,此时应继续向该方向搜索离之最近的点。
感觉实现的时候还是比较多细节要注意的。
代码如下:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<vector> using namespace std; #define mod 1005 const int U=1,D=2,L=3,R=4; int r,c,n,t,x,y; struct drop{ int x,y,size,status,time,num,dir; bool operator < (const drop d) const{ return time>d.time; } }drops[105]; int update(int num,int dir){ int closest=-1; for(int i=0;i<n;i++) if(drops[i].status&&i!=num){ if(dir==U){ if(drops[num].x==drops[i].x&&drops[num].y<drops[i].y) if(closest==-1||drops[i].y<drops[closest].y) closest=i; } else if(dir==D){ if(drops[num].x==drops[i].x&&drops[num].y>drops[i].y) if(closest==-1||drops[i].y>drops[closest].y) closest=i; } else if(dir==L){ if(drops[num].y==drops[i].y&&drops[num].x>drops[i].x) if(closest==-1||drops[i].x>drops[closest].x) closest=i; } else{ if(drops[num].y==drops[i].y&&drops[num].x<drops[i].x) if(closest==-1||drops[i].x<drops[closest].x) closest=i; } } return closest; } priority_queue<drop>pq; vector<drop> T; int main(){ for(int i=0;i<105;i++) drops[i].num=i; //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d%d%d",&r,&c,&n,&t)){ for(int i=0;i<n;i++){ scanf("%d%d%d",&drops[i].x,&drops[i].y,&drops[i].size); drops[i].status=1,drops[i].time=10005; } scanf("%d%d",&x,&y); while(!pq.empty()) pq.pop(); drops[100].x=x,drops[100].y=y,drops[100].status=1; drops[100].size=4,drops[100].time=0; pq.push(drops[100]); int t_now=0; while(!pq.empty()){ drop tmp=pq.top(); while(!drops[tmp.num].status){ pq.pop(); int num=update(tmp.num,tmp.dir); if(num!=-1){ drop temp=drops[num]; temp.dir=tmp.dir; if(temp.dir==U) temp.time=temp.y-tmp.y; else if(temp.dir==D) temp.time=tmp.y-temp.y; else if(temp.dir==L) temp.time=tmp.x-temp.x; else temp.time=temp.x-tmp.x; temp.time+=tmp.time; pq.push(temp); } if(pq.empty()) break; else tmp=pq.top(); } if(pq.empty()) break; if(tmp.time>t) break; int up=-1,down=-1,left=-1,righ=-1; if(drops[tmp.num].size<4){ drops[tmp.num].size++; pq.pop(); continue; } pq.pop();//new T.clear(); while(!pq.empty()){ drop Tmp=pq.top(); if(Tmp.time==tmp.time&&Tmp.x==tmp.x&&Tmp.y==tmp.y) pq.pop(); else if(Tmp.time==tmp.time){ T.push_back(Tmp); pq.pop(); } else break; } for(int i=0;i<T.size();i++) pq.push(T[i]); drops[tmp.num].status=0; drops[tmp.num].time=tmp.time; t_now=drops[tmp.num].time; for(int i=0;i<n;i++) if(drops[i].status){ if(tmp.x==drops[i].x){ if(tmp.y<drops[i].y){ if(up==-1||drops[i].y<drops[up].y) up=i; } else{ if(down==-1||drops[i].y>drops[down].y) down=i; } } else if(tmp.y==drops[i].y){ if(tmp.x>drops[i].x){ if(left==-1||drops[i].x>drops[left].x) left=i; } else{ if(righ==-1||drops[i].x<drops[righ].x) righ=i; } } } if(up!=-1&&drops[up].time>drops[up].y-tmp.y+t_now){ drop temp=drops[up]; temp.time=drops[up].y-tmp.y+t_now,temp.dir=U; pq.push(temp); } if(down!=-1){ drop temp=drops[down]; temp.time=tmp.y-drops[down].y+t_now,temp.dir=D; pq.push(temp); } if(left!=-1){ drop temp=drops[left]; temp.time=tmp.x-drops[left].x+t_now,temp.dir=L; pq.push(temp); } if(righ!=-1){ drop temp=drops[righ]; temp.time=drops[righ].x-tmp.x+t_now,temp.dir=R; pq.push(temp); } //pq.pop(); } for(int i=0;i<n;i++){ if(drops[i].status) printf("1 %d\n",drops[i].size); else printf("0 %d\n",drops[i].time); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/names-yc/p/4703137.html