http://acm.hdu.edu.cn/showproblem.php?pid=5336
4 4 5 10 2 1 4 2 3 3 2 4 4 3 1 2 4 3 4 4 4
0 5 0 3 0 2 1 3 0 1
/** hdu5336 多校联合第四场1010 模拟+bfs 题目大意:很像一个游戏“十滴水”,在一个n*m的棋盘里有N个点有一些水滴,含水量为1~4,如果一滴水多于4则该水滴会向四个方向放射量为1 的水,并且原位置水滴消逝,放射的水运动速度为1格/s,最开始在xy位置有一滴水崩裂,问T s时各初始状态的水滴的状态是什么 解题思路:因为水滴的迸射会产生连锁反应,因此我们用优先队列维护,bfs。 值得一提的是如果2或以上的水同时到达一水滴,并该水滴迸射那么这些水滴同时消失。 */ #include <string.h> #include <algorithm> #include <iostream> #include <stdio.h> #include <queue> using namespace std; int n,m,N,T,num[1005][2],sta[1005][1005],time[1005][1005]; int dx[][2]= {1,0,0,1,-1,0,0,-1}; struct note { int x,y,d,t; note() {} note(int _x,int _y,int _d,int _t) { x=_x,y=_y,d=_d,t=_t; } bool operator < (const note &other)const { return t>other.t; } }; void bfs(int x,int y) { memset(time,-1,sizeof(time)); priority_queue<note> q; q.push(note(x,y,0,0)); q.push(note(x,y,1,0)); q.push(note(x,y,2,0)); q.push(note(x,y,3,0)); while(!q.empty()) { note cnt=q.top(); if(cnt.t>=T)return; q.pop(); x=cnt.x+dx[cnt.d][0]; y=cnt.y+dx[cnt.d][1]; if(x<=0||x>n||y<=0||y>m||time[x][y]==cnt.t+1)continue; if(sta[x][y]!=0) { if(sta[x][y]==4) { sta[x][y]=0; time[x][y]=cnt.t+1; q.push(note(x,y,0,cnt.t+1)); q.push(note(x,y,1,cnt.t+1)); q.push(note(x,y,2,cnt.t+1)); q.push(note(x,y,3,cnt.t+1)); } else { sta[x][y]++; } } else q.push(note(x,y,cnt.d,cnt.t+1)); } } int main() { while(~scanf("%d%d%d%d",&n,&m,&N,&T)) { memset(sta,0,sizeof(sta)); for(int i=0; i<N; i++) { int x; scanf("%d%d%d",&num[i][0],&num[i][1],&x); sta[num[i][0]][num[i][1]]=x; } int x,y; scanf("%d%d",&x,&y); bfs(x,y); for(int i=0; i<N; i++) { if(time[num[i][0]][num[i][1]]==-1) printf("1 %d\n",sta[num[i][0]][num[i][1]]); else printf("0 %d\n",time[num[i][0]][num[i][1]]); } } return 0; }