HDU 5336多校 十滴水模拟

Problem Description

XYZ is playing an interesting game called "drops". It is played on a r?c 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 (x, y),
before the first second there is a waterdrop cracking at position (x, y).
XYZ wants to know each waterdrop‘s status after Tseconds,
can you help him?

1≤r≤100, 1≤c≤100, 1≤n≤100, 1≤T≤10000

Input

The first line contains four integers r, c, n and T. n stands
for the numbers of waterdrops at the beginning.

Each line of the following n lines
contains three integers xi, yi, sizei,
meaning that the i-th
waterdrop is at position (xi, yi)
and its size is sizei.
(1≤sizei≤4)

The next line contains two integers x, y.

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 Ai, Bi:

If the i-th
waterdrop cracks in T seconds, Ai=0, Bi= the
time when it cracked.

If the i-th
waterdrop doesn‘t crack in T seconds, Ai=1, Bi= 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

第一种方法是枚举的时间,效率较低,比赛时跑了265ms。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#define ll long long
using namespace std;
int jl[1110];
int r,c,n,t;
struct node
{
    int x,y,d;
};
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int Map[110][110];
struct node2
{
    int water,time;
};
node2 ans [110][110];
int in(int x,int y)
{
    if(x>=1&&x<=r&&y>=1&&y<=c)
        return 1;
    return 0;
}
queue<node> q;
queue<node> q2;
int bfs( )
{
    node next,tmp,fen;
    int xx,yy;
    for(int ttt = 0; ttt<=t; ttt++)
    {
//        for(int i=1; i<=r; i++)
//        {
//            for(int j=1; j<=c; j++)
//            {
//                cout<<Map[i][j]<<" ";
//            }
//            cout<<endl;
//        }
//        cout<<endl;
        for(int i=0; i<n; i++)
        {
            xx = jl[i]/1000, yy = jl[i]%1000;
            if(Map[xx][yy]>4)
            {
                Map[xx][yy]  = 0;
                ans[xx][yy].water =  0;
                ans[xx][yy].time  =  ttt;
                for(int j=0; j<4; j++)
                {
                    fen.x = xx,fen.y = yy,fen.d = j;
                    q.push(fen);
                }
            }
            else
            {
                ans[xx][yy].water = Map[xx][yy];
            }
        }
        while(!q.empty())
        {
            node tmp = q.front();
            q.pop();
            int xx = tmp.x + dir[tmp.d][0];
            int yy = tmp.y + dir[tmp.d][1];
            if(!in(xx,yy))
                continue;
            if(Map[xx][yy]==0)
            {
                next.x = xx;
                next.y = yy;
                next.d = tmp.d;
                q2.push(next);
            }
            else
                Map[xx][yy] ++;
        }
        while(!q2.empty())
        {
            q.push(q2.front());
            q2.pop();
        }
    }
    return 0;
}
int main()
{
    while(cin>>r>>c>>n>>t)
    {
        memset(Map,0,sizeof(Map));
        for(int i=0; i<n; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            jl[i] = x*1000+y;
            ans[x][y].water = z;
            ans[x][y].time = 0;
            Map[x][y] += z;
        }
        int sx,sy;
        cin>>sx>>sy;
        while(!q.empty())
            q.pop();
        while(!q2.empty())
            q.pop();
        node tmp;
        for(int i=0; i<4; i++)
        {
            tmp.x = sx,tmp.y = sy;
            tmp.d = i;
            q.push(tmp);
        }
        bfs();
        int ex,ey;
        node2 flag ;
        for(int i=0; i<n; i++)
        {
            ex = jl[i]/1000;
            ey = jl[i]%1000;
            flag = ans[ex][ey];
            if(flag.water == 0)
                cout<<0<<" "<<flag.time<<endl;
            else
                cout<<1<<" "<<flag.water<<endl;
        }
    }
    return 0;
}

第二种方法只需把当前这一秒所有的小水珠都处理完再判断是否爆裂。赛后跑了46ms。

据说是赛前该小了数据,要不然第一种方法就会T掉。

</pre><pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#define ll long long
using namespace std;
int jl[1110];
int r,c,n,t;
struct node
{
    int x,y,d;
    int mov;
};
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int Map[110][110];
struct node2
{
    int water,time;
};
node2 ans [110][110];
int in(int x,int y)
{
    if(x>=1&&x<=r&&y>=1&&y<=c)
        return 1;
    return 0;
}
queue<node> q;
int bfs( )
{
    node next,tmp,fen;
    int xx,yy;
    while(!q.empty()&&q.front().mov<t)
    {
        node tmp = q.front();
        q.pop();
        int xx = tmp.x + dir[tmp.d][0];
        int yy = tmp.y + dir[tmp.d][1];
      //  if(in(xx,yy))  continue;
      //如果后面还有判断条件 ,不要这样写
        if(in(xx,yy))
        {
            if(Map[xx][yy]==0)
            {
                next.x = xx;
                next.y = yy;
                next.d = tmp.d;
                next.mov = tmp.mov + 1;
                q.push(next);
            }
            else
                Map[xx][yy] ++;
        }
        if(q.empty()||q.front().mov != tmp.mov)
        {
            for(int i=0; i<n; ++i)
            {
                xx = jl[i]/1000, yy = jl[i]%1000;
                if(Map[xx][yy]>4)
                {
                    Map[xx][yy]  = 0;
                    ans[xx][yy].water =  0;
                    ans[xx][yy].time  =  tmp.mov + 1;
                    for(int j=0; j<4; ++j)
                    {
                        fen.x = xx,fen.y = yy,fen.d = j;
                        fen.mov = tmp.mov + 1;
                        q.push(fen);
                    }
                }
                else
                    ans[xx][yy].water = Map[xx][yy];
            }
        }
    }
    return 0;
}
int main()
{
    while(scanf("%d%d%d%d",&r,&c,&n,&t)!=EOF)
    {
        memset(Map,0,sizeof(Map));
        for(int i=0; i<n; ++i)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            jl[i] = x*1000+y;
            ans[x][y].water = z;
            ans[x][y].time = 0;
            Map[x][y] += z;
        }
        int sx,sy;
        scanf("%d%d",&sx,&sy);

        while(!q.empty())
            q.pop();
        node tmp;
        for(int i=0; i<4; ++i)
        {
            tmp.x = sx,tmp.y = sy;
            tmp.d = i;
            tmp.mov  = 0;
            q.push(tmp);
        }
        bfs();
        int ex,ey;
        node2 flag ;
        for(int i=0; i<n; ++i)
        {
            ex = jl[i]/1000;
            ey = jl[i]%1000;
            flag = ans[ex][ey];
            if(flag.water == 0)
                printf("0 %d\n",flag.time);

            else
               printf("1 %d\n",flag.water);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-07 21:45:01

HDU 5336多校 十滴水模拟的相关文章

Hdu 5336 XYZ and Drops (bfs 模拟)

题目链接: Hdu 5336 XYZ and Drops 题目描述: 有一个n*m的格子矩阵,在一些小格子里面可能会有一些水珠,每个小水珠都有一个size.现在呢,游戏开始咯,在一个指定的空的小格子里面有一个将要向四周爆裂的水珠,在下一面分别向上,下,左,右四个方向发射一个小水滴,(小水滴与水珠同,小水滴没有size),当小水滴走向一个格子,这个格子如果是空或者有其他的小水滴同时走到这个格子的情况下,对小水滴的运动轨迹是不影响的.但是遇到水珠的话,小水滴就会被吸收,水珠每次吸收一个小水滴size

hdu 4915 Parenthese sequence(模拟)2014多校训练第5场

Parenthese sequence                                                                     Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description bobo found an ancient string. The string contains only t

HDU 5336(2015多校4)-XYZ and Drops(bfs)

题目地址:HDU 5336 题意:有一个r 行 c 列的格子,给出n个格子里有水滴的大小.再给出时间限制T,使得水滴从(sx,sy)位置开始爆破,当飞渐的水遇到格子里的静态水时就会聚在一起,当聚集的水滴大小>4时就会爆破.问在T时给定的n个位置格子里的水滴情况,如果没有爆破就输出:1 格子里水滴大小.否则输出:0 爆破的时间. #include <stdio.h> #include <math.h> #include <string.h> #include <

Hdu 3887树状数组+模拟栈

题目链接 Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 582 Problem Description You are given a tree, it’s root is p, and the node is numbered fr

hdu 4891 The Great Pan(模拟)

题目链接:hdu 4891 The Great Pan 题目大意:给出一个文本,问说有多少种理解方式. 1. $$中间的,(s1+1) * (s2+1) * ...*(sn+1), si表示连续的空格数. 2.{}中间,即 | 的个数+1. 解题思路:模拟. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1<<22

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 352    Accepted Submission(s): 104 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

HDU 4930 Fighting the Landlords 模拟

_(:зゝ∠)_ 4带2居然不是炸弹,, #include <algorithm> #include <cctype> #include <cassert> #include <cstdio> #include <cstring> #include <climits> #include <vector> #include<iostream> using namespace std; #define N 18 #

hdu 1316 How Many Fibs? (模拟高精度)

题目大意: 问[s,e]之间有多少个 斐波那契数. 思路分析: 直接模拟高精度字符串的加法和大小的比较. 注意wa点再 s 可以从 0 开始 那么要在判断输入结束的时候注意一下. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; struct node { char str[111]; int len; void

HDU 4831 Scenic Popularity 暴力模拟

Scenic Popularity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 340    Accepted Submission(s): 110 Problem Description 临近节日,度度熊们最近计划到室外游玩公园,公园内部包括了很多的旅游景点区和休息区,由于旅游景点很热门,导致景点区和休息区都聚集了很多人.所以度度熊