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
题意:水滴和小水滴是有区别的
小水滴不会合并,但是会被水滴吃掉。初始会给一个位置,水滴爆炸了。
如果一个水滴的大小>4水滴会爆掉,产生4个小水滴,向四个方向移动,
问一个水滴如果爆掉,什么时间爆的。如果没爆掉,输出水滴最后的大小。
分析:小水滴最多4n个,直接模型小水滴的移动,如果遇到水滴,则合并,再判断合并后的水滴是否爆炸。
解题报告提到如果r,c,n <= 100000,T <= 10^9的时候怎么处理
这时考虑用十字链表构建整个水滴网络,最多有4n个小水滴,每个小水滴最多被合并一次。
对于每个水滴,爆炸的时候能够立刻算出小水滴与一下个水滴合并的时间。用一个数据
结构维护合并时间最小的事件,然后模拟即可。
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using namespace std; int map[101][101]; struct Point{ int x,y,xu,yu; Point(){} Point fu(int dx,int dy){ Point a; a.x = x, a.y = y, a.xu = dx, a.yu = dy; return a; } }; vector<Point> baozha; vector<Point> shuidi; vector<Point> ans; vector<Point> les; int dir[4][2] = { 0,1, 1,0, -1,0, 0,-1 }; int main(){ int r,c,n,t; while(scanf("%d%d%d%d",&r,&c,&n,&t)!=EOF){ memset(map,0,sizeof(map)); baozha.clear(); shuidi.clear(); ans.clear(); Point a,b; int u; for(int i = 0;i < n; i++){ scanf("%d%d%d",&a.x,&a.y,&u); map[a.x][a.y] = u; ans.push_back(a); } scanf("%d%d",&a.x,&a.y); for(int i = 0;i < 4; i++) baozha.push_back(a.fu(dir[i][0],dir[i][1])); for(int tt = 1; tt <= t; tt++){ if(baozha.size() == 0) break; les.clear(); shuidi.clear(); for(int i = 0;i < baozha.size(); i++){ a = baozha[i]; a.x += a.xu, a.y += a.yu; if(a.x <= 0 || a.x > r || a.y <= 0 || a.y > c) continue; if(map[a.x][a.y] > 0){ map[a.x][a.y]++; if(map[a.x][a.y] > 4) shuidi.push_back(a); } else les.push_back(a); } baozha.clear(); for(int i = 0;i < shuidi.size(); i++){ a = shuidi[i]; if(map[a.x][a.y] <=0) continue; for(int j = 0; j < 4; j++) baozha.push_back(a.fu(dir[j][0],dir[j][1])); map[a.x][a.y] = -tt; } for(int i = 0;i < les.size();i++) baozha.push_back(les[i]); } for(int i = 0;i < n; i++){ a = ans[i]; if(map[a.x][a.y] > 0 ){ printf("1 %d\n",map[a.x][a.y]); } else printf("0 %d\n",-map[a.x][a.y]); } } return 0; }