题意就不细说了,背景和玩法和模拟细节就是 经典小游戏十滴水(http://www.7k7k.com/swf/15746.htm),大家自己去玩就行。
约定:以下文字中,称题面里的waterdrop为水滴,small drops为水珠。
题目描述里遗漏了很多细节,这里根据比赛里正确的Clarification里的回应补充一下:
接下来讨论一下这种推演一定时间后的情况的模拟题应该如何去实现。一般有2种思路:
#include <stdio.h> #include <queue> using namespace std; const int di[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; const int MAXN=100; struct Drop{ int x,y,d; Drop(){} Drop(int a,int b,int c):x(a),y(b),d(c){} Drop next(){ return Drop(x+di[d][0],y+di[d][1],d); } }input[MAXN+5]; int mp[MAXN+5][MAXN+5]; int crackTime[MAXN+5]; int main(){ int r,c,n,T; int tmpx,tmpy; for(;~scanf("%d%d%d%d",&r,&c,&n,&T);){ for(int i=0;i<=r;i++){ for(int j=0;j<=c;j++){ mp[i][j]=0; } } for(int i=0;i<n;i++){ scanf("%d%d%d",&input[i].x,&input[i].y,&input[i].d); mp[input[i].x][input[i].y]=input[i].d; crackTime[i]=0; } scanf("%d%d",&tmpx,&tmpy); queue<Drop> q; for(int i=0;i<4;i++){ q.push(Drop(tmpx,tmpy,i)); } for(int time=1;time<=T;time++){ int len=q.size(); if(len==0)break; for(int i=0;i<len;i++){ Drop tmp=q.front();q.pop(); tmp=tmp.next(); if(tmp.x<=0||tmp.y<=0||tmp.x>r||tmp.y>c)continue; if(mp[tmp.x][tmp.y]){ mp[tmp.x][tmp.y]++; }else{ q.push(tmp); } } for(int i=0;i<n;i++){ if(mp[input[i].x][input[i].y]>4){ for(int j=0;j<4;j++){ q.push(Drop(input[i].x,input[i].y,j)); } crackTime[i]=time; mp[input[i].x][input[i].y]=0; } } } for(int i=0;i<n;i++){ if(crackTime[i]){ printf("0 %d\n",crackTime[i]); }else printf("1 %d\n",mp[input[i].x][input[i].y]); } } return 0; }(喂,一个Drop结构体,或者说,类,做了2件事情啊!)
#include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <math.h> #include <algorithm> #include <set> #include <queue> using namespace std; typedef long long ll; const int MAXN=100; struct INDEX{ int key,value; INDEX(){} INDEX(int k,int v):key(k),value(v){} bool operator<(const INDEX&b)const{ return key<b.key; } }; set<INDEX> row[MAXN+5],col[MAXN+5]; const int di[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; struct Drop{ int t,x,y,d,idx; Drop(){} Drop(int T,int a,int b,int c,int IDX):t(T),x(a),y(b),d(c),idx(IDX){} bool operator<(const Drop&b)const{ return t>b.t; } Drop forward(){ set<INDEX>::iterator it; if(d<=1){ it=col[y].lower_bound(INDEX(x,0)); if(d==0)it--; if(it->value<0)return Drop(-1,0,0,0,-1); return Drop(t+abs(x-(it->key)),it->key,y,d,it->value); }else{ it=row[x].lower_bound(INDEX(y,0)); if(d==2)it--; if(it->value<0)return Drop(-1,0,0,0,-1); return Drop(t+abs(y-(it->key)),x,it->key,d,it->value); } } }; int size[MAXN+5]; int crackTime[MAXN+5]; int main(){ int Case=1; int r,c,n,T; int tmpx,tmpy,tmpz; for(;~scanf("%d%d%d%d",&r,&c,&n,&T);){ for(int i=0;i<=r;i++){row[i].clear();row[i].insert(INDEX(c+1,-1));row[i].insert(INDEX(0,-1));} for(int i=0;i<=c;i++){col[i].clear();col[i].insert(INDEX(r+1,-1));col[i].insert(INDEX(0,-1));} for(int i=0;i<n;i++){ scanf("%d%d%d",&tmpx,&tmpy,&tmpz); crackTime[i]=0; size[i]=tmpz; row[tmpx].insert(INDEX(tmpy,i)); col[tmpy].insert(INDEX(tmpx,i)); } scanf("%d%d",&tmpx,&tmpy); priority_queue<Drop> q; for(int i=0;i<4;i++){ Drop t(0,tmpx,tmpy,i,0); t=t.forward(); if(t.t>=0&&t.t<=T) q.push(t); } while(!q.empty()){ Drop x=q.top();q.pop(); int idx=x.idx; if(crackTime[idx]){ if(crackTime[idx]<x.t){ x=x.forward(); if(x.t>=0&&x.t<=T) q.push(x); } }else{ if(size[idx]){ size[idx]++; if(size[idx]>4){ crackTime[idx]=x.t; size[idx]=0; row[x.x].erase(INDEX(x.y,0)); col[x.y].erase(INDEX(x.x,0)); for(int i=0;i<4;i++){ Drop t(x.t,x.x,x.y,i,0); t=t.forward(); if(t.t>=0&&t.t<=T) q.push(t); } } }else{ x=x.forward(); if(x.t>=0&&x.t<=T) q.push(x); } } } for(int i=0;i<n;i++){ if(crackTime[i]){ printf("0 %d\n",crackTime[i]); }else printf("1 %d\n",size[i]); } } return 0; }