hdu 5336 XYZ and Drops

本文介绍了一种模拟水滴在二维平面上扩散的算法。通过暴力模拟的方式追踪多个水滴的状态变化,解决水滴碰撞及扩散的问题。算法的时间复杂度为O(n*T),适用于处理大规模的水滴扩散场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


暴力模拟每个水滴和小水滴的状态即可,复杂度O(n*T)。

(大家可以想一下1<= r <= 100000,1 <= c <= 100000, 1<=  n <= 100000, 1<= T <= 1000000000的时候怎么做)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;

const int maxn=110;
struct node
{
    int x,y,val,t;
}no[maxn];
struct water
{
    int x,y,t,id,dir;
    water(){}
    water(int _x,int _y,int _t,int _id,int _dir):x(_x),y(_y),t(_t),id(_id),dir(_dir){}
    bool operator < (const water &a) const
    {
        return t > a.t;
    }
};

int r,c,n,T;
int vis[maxn][maxn];

void solve(int x,int y,priority_queue<water> &q,int t)
{
    int tmp = x;
    vis[x][y] = -1;
    while(tmp>0 && vis[tmp][y]==-1)
        tmp--;
    q.push(water(tmp,y,t+x-tmp,tmp==0?-1:vis[tmp][y],1));
    tmp = x;
    while(tmp<=r && vis[tmp][y]==-1)
        tmp++;
    q.push(water(tmp,y,t+tmp-x,tmp>r?-1:vis[tmp][y],2));
    tmp = y;
    while(tmp>0 && vis[x][tmp]==-1)
        tmp--;
    q.push(water(x,tmp,t+y-tmp,tmp==0?-1:vis[x][tmp],3));
    tmp = y;
    while(tmp<=c && vis[x][tmp]==-1)
        tmp++;
    q.push(water(x,tmp,t+tmp-y,tmp>c?-1:vis[x][tmp],4));
}
void bfs(int x,int y)
{
    priority_queue<water> q;
    solve(x,y,q,0);

    while(!q.empty())
    {
        water u = q.top();
        q.pop();
        if(u.id == -1)
            continue;
        if(u.t > T)
            continue;
        if(no[u.id].val <= 4 && vis[u.x][u.y] != -1)
        {
            no[u.id].t = u.t;
            no[u.id].val++;
            if(no[u.id].val>4)
                solve(no[u.id].x,no[u.id].y,q,u.t);
        }
        else if(no[u.id].val>4 && no[u.id].t<u.t)
        {
            int x = u.x,y = u.y;
            int tmp,t = u.t;
            if(u.dir == 1)
            {
                tmp = x;
                while(tmp>0 && vis[tmp][y]==-1)
                    tmp--;
                if(tmp > 0)
                    q.push(water(tmp,y,t+x-tmp,vis[tmp][y],1));
            }
            else if(u.dir == 2)
            {
                tmp = x;
                while(tmp<=r && vis[tmp][y]==-1)tmp++;
                if(tmp <= r)
                    q.push(water(tmp,y,t+tmp-x,vis[tmp][y],2));
            }
            else if(u.dir == 3)
            {
                tmp = y;
                while(tmp>0 && vis[x][tmp]==-1)
                    tmp--;
                if(tmp > 0)
                    q.push(water(x,tmp,t+y-tmp,vis[x][tmp],3));
            }
            else
            {
                tmp = y;
                while(tmp<=c && vis[x][tmp]==-1)
                    tmp++;
                if(tmp <= c)
                    q.push(water(x,tmp,t+tmp-y,vis[x][tmp],4));
            }
        }
    }
}

int main()
{
    while(scanf("%d%d%d%d",&r,&c,&n,&T)!=EOF)
    {
        memset(vis,-1,sizeof(vis));
        for(int i = 1;i <= n; i++)
        {
            scanf("%d%d%d",&no[i].x,&no[i].y,&no[i].val);
            vis[no[i].x][no[i].y] = i;
        }
        int x,y;
        scanf("%d%d",&x,&y);
        bfs(x,y);
        for(int i = 1; i <= n; i++)
        {
            if(no[i].val > 4)
                printf("0 %d\n",no[i].t);
            else
                printf("1 %d\n",no[i].val);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值