hdu5334 XYZ and Drops(BFS)

XYZ and Drops

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2111    Accepted Submission(s): 730


Problem Description
XYZ is playing an interesting game called "drops". It is played on a rc grid. Each grid cell is either empty, or occupied by a waterdrop. Each waterdrop has a property "size". The waterdrop cracks when its size is larger than 4, and produces 4 small drops moving towards 4 different directions (up, down, left and right). 

In every second, every small drop moves to the next cell of its direction. It is possible that multiple small drops can be at same cell, and they won't collide. Then for each cell occupied by a waterdrop, the waterdrop's size increases by the number of the small drops in this cell, and these small drops disappears. 

You are given a game and a position (xy), before the first second there is a waterdrop cracking at position (xy). XYZ wants to know each waterdrop's status after Tseconds, can you help him?

1r1001c1001n1001T10000
 

Input
The first line contains four integers rcn and Tn stands for the numbers of waterdrops at the beginning. 
Each line of the following n lines contains three integers xiyisizei, meaning that the i-th waterdrop is at position (xiyi) and its size is sizei. (1sizei4)
The next line contains two integers xy

It is guaranteed that all the positions in the input are distinct. 

Multiple test cases (about 100 cases), please read until EOF (End Of File).
 

Output
n lines. Each line contains two integers AiBi
If the i-th waterdrop cracks in T seconds, Ai=0Bi= the time when it cracked. 
If the i-th waterdrop doesn't crack in T seconds, Ai=1Bi= its size after T seconds.
 

Sample Input
4 4 5 10 2 1 4 2 3 3 2 4 4 3 1 2 4 3 4 4 4
 

Sample Output
0 5 0 3 0 2 1 3 0 1
題意:十滴水遊戲,當一個格子的水滴>4就爆炸,分成上下左右的四個水滴,求t秒時,每個格子的狀態

根據時間模擬每個水滴即可

注意:多個水滴相同時間到達一個原本含有水滴的位置,比如一個位置原本有4滴水,然後有2滴水同時到達,此時他是從6滴水的狀態爆破成4滴水(也就是注意“相同時間“的水滴)

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int n,m;
struct node
{
    node() {}
    node(int a,int b,int c,int d)
    {
        x=a,y=b,t=c,op=d;
    }
    int x,y,t,op;
    bool friend operator <(node A,node B)
    {
        return A.t>B.t;
    }
} ;
struct edge
{
    int x,y;
} e[105];
int go[4][2]= {1,0,0,1,-1,0,0,-1};
int g[105][105],re[105][105],ans[105];
void bfs(int x,int y,int s)
{
    priority_queue<node>q;
    //優先隊列可以保證每次選取時間最小的水滴
    q.push(node(x,y,0,4));
    while(!q.empty())
    {
        node u=q.top();
        q.pop();
        //狀態爲4的水滴表示需要爆破
        if(u.op==4)
        {
            ans[re[u.x][u.y]]=u.t;
            g[u.x][u.y]=0;
            for(int i=0; i<4; i++)
                q.push(node(u.x,u.y,u.t,i));
        }
        else
        {
            if(u.t>=s)continue;
            int tx=go[u.op][0]+u.x;
            int ty=go[u.op][1]+u.y;
            if(!(tx>=1&&tx<=n&&ty>=1&&ty<=m))continue;
            if(g[tx][ty])
            {
                //此處如此處理可將需爆破的水滴只入隊一次,且還能繼續更新相同時間的水滴狀態(注意裏說的那種情況)
                if(g[tx][ty]==4)q.push(node(tx,ty,u.t+1,4));
                g[tx][ty]++;
            }
            else
                q.push(node(tx,ty,u.t+1,u.op));
        }
    }
}
int main()
{
    int t,x,y,k,num;
    while(cin>>n>>m>>k>>t)
    {
        mem(ans,0);
        mem(g,0);

        for(int i=1; i<=k; i++)
        {
            cin>>e[i].x>>e[i].y>>num;
            g[e[i].x][e[i].y]=num;
        }
        cin>>x>>y;
        bfs(x,y,t);
        for(int i=1; i<=k; i++)
        {
            if(!ans[i])
                printf("1 %d\n",g[e[i].x][e[i].y]);
            else
                printf("0 %d\n",ans[i]);
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章