解题思路

这题思路并不难,主要问题是,不太好编码实现(可能是本人练习不够吧),因为有个时间在里面,而且每个小水滴都同时流动,感觉好复杂的样子。比赛时,我首先想到的是DFS+时间流做参数,由于比赛时神经紧张,思路比较混乱,没写出来,放弃了。比赛结束后,冷静下来思考后,这题应该用BFS更合适,只要在“水滴”这个结构体中定义时间参数就好。对于这种带“时间”运动的典型题型,用BFS更合适。代码结构和思路和常规的BFS基本一样,而且都不用循环扫描4个方向,因为小水滴是一路向前走的。

注意

1、如果两个小水滴相遇,不是形成水坑,而是擦肩而过(注定它俩没缘分......)。比赛时心里总想着看题速度要快,然后主观臆断,认为两个小水滴相遇会形成大小为1+1=2的水坑,导致理解错题目意思。。。。。。。看再快也是白搭。所以,磨刀不误砍柴工,看题一定要仔细,理解清楚题目意思,否则一切都是瞎扯淡。

2、如果多个水滴同时到达一个水坑,那么,如果水坑爆炸,这多个水滴都会连带进去消失。比如:如果原水坑大小为4,有3个水滴同时过来,那么,他们合在一起再爆炸,分解成4小水滴。也就是:(4+3)/4 = 1。因为程序执行是单线程的,逻辑上同时到达同一个位置的水滴在执行时时间不一致,所以需要考虑这么一种情况。也就是说,当A水滴到达水坑W后,W爆炸,分解成4个不同方向的小水滴。然后B水滴(到达水坑W的时间和A相同)也流到水坑W时,逻辑上他和A应该时一起进入W然后爆炸的,但是如果不判断,那么,B水滴会继续向前流,这就不对了。

片花:果然“水坑”题是又水又坑。。。。。。

代码

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

const int dirs[][2] = {{0, -1}, {0, 1}, { -1, 0}, {1, 0}};
typedef struct {
    int x, y;
} Water;//水坑
typedef struct {
    int x, y, t, dir;
} Drop;//水滴
int r, c, n, t;
Drop st[4];
/*sz[x][y]:坐标(x, y)位置的水坑的大小。boom[x][y]:坐标(x, y)位置的水坑爆炸的时间。*/
int sz[110][110], boom[110][110];
vector<Water> ds;
queue<Drop> que;

void bfs() {
    while(!que.empty())que.pop();
    for(int i = 0; i < 4; i++)que.push(st[i]);
    while(!que.empty()) {
        Drop d = que.front();
        que.pop();
        /*这个地方:continue和return都行。
        为什么呢?continue表示对队列中剩余的小水滴也依次处理。
        因为我们用的是BFS,如果当前小水滴d的生存时间为t了,
        那么,后面的小水滴肯定为t(因为t+1也是由t推出的。而水滴生存时间到了t就不能再流动了)。
        所以后面的小水滴同样会做这个处理。
        而return直接结束BFS,因为实际上后面的操作都是没必要的。
        然而:HDUOJ上实测,continue运行时间31ms,return运行时间46ms.
        */
        if(d.t >= t)continue;
        int nx = d.x + dirs[d.dir][0], ny = d.y + dirs[d.dir][1];
        /*前4个条件判断越界,最后一个条件是考虑这种情况:
            两个或多个水滴同时向一个水坑流去,那么,如果水坑爆炸了,
            boom[nx][ny] == d.t + 1。由于我们的程序执行是单线程的,
            逻辑上时间相同而实际上代码运行时的时间不同。所以,这个条件就是说,
            对于当前水滴的后几个水滴(这几个水滴到达(nx, ny)这个水坑的时间相同),
            如果(nx, ny)这个位置的水坑爆炸了,那么,逻辑上,当前水滴的后几个水滴
            都应该是连带进去爆炸的。因为他们到达这个水坑的时间相同。
        */
        if(nx < 1 || nx > r || ny < 1 || ny > c || boom[nx][ny] == d.t + 1)continue;
        if(sz[nx][ny] > 0) {
            sz[nx][ny]++;
            if(sz[nx][ny] > 4) {
                boom[nx][ny] = d.t + 1;
                /*分解成4个方向的水滴。*/
                for(int i = 0;i < 4;i++)que.push((Drop) {nx, ny, d.t + 1, i});
                sz[nx][ny] = 0;
            }
        }
        /*小水滴继续向前流*/
        else que.push((Drop) {nx, ny, d.t + 1, d.dir});
    }
}

void init() {
    ds.clear();
    memset(sz, 0, sizeof(sz));
    memset(boom, -1, sizeof(boom));
}

int main() {
    int x, y, szz;
    while(scanf("%d%d%d%d", &r, &c, &n, &t) != EOF) {
        init();
        for(int i = 0; i < n; i++) {
            scanf("%d%d%d", &x, &y, &szz);
            sz[x][y] = szz;
            ds.push_back((Water) {x, y});
        }
        scanf("%d%d", &st[0].x, &st[0].y);
        st[0].t = 0, st[0].dir = 0;
        for(int i = 1; i < 4; i++) {
            st[i] = st[0];
            st[i].dir = i;
        }
        bfs();

        Water w;
        for(int i = 0; i < ds.size(); i++) {
            w = ds[i];
            if(boom[w.x][w.y] >= 0)printf("0 %d\n", boom[w.x][w.y]);
            else printf("1 %d\n", sz[w.x][w.y]);
        }
    }
    return 0;
}

加油,不要怕,相信自己一定可以的!

HDU5336题解的更多相关文章

  1. hdu5336 Walk Out

    hdu5336 Walk Out 题意是:入口:地图的左上角,出口,地图的右上角,求所经过的路径的二进制数最小 照着题解敲了一遍 思路是:首先 二进制 的 位数 越小 越好,其次 二进制的前缀零越多 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. ASP.NET MVC3关于生成纯静态后如何不再走路由直接访问静态页面--收藏没测

    要解决这个问题,我们需要先了解ASP.NET应用程序的生命周期,先看下面作者整理的一张图片: 从图中我们可以清楚的看到:通用IIS访问应用程序时,每次的单个页面URL访问时,都会先经过HttpAppl ...

  2. root用户下使用sqlplus登录Oracle数据库

    1.把环境变量添加到root用户的环境变量里面2.执行 chmod -R 6777 /tmp           chmod -R 6777 /usr/tmp           chmod -R 6 ...

  3. 利用xcopy在复制文件或文件夹的时候保留其权限

    当用 Windows Explorer 复制或移动文件和文件夹时,文件或文件夹上设置的权限可能会发生改变.例如,当在一个 NTFS文件系统卷内或在两个 NTFS 卷之间复制一个文件时,Windows将 ...

  4. 機器學習基石 机器学习基石(Machine Learning Foundations) 作业1 习题解答 (续)

    这里写的是  习题1 中的    18 , 19, 20 题的解答. Packet 方法,我这里是这样认为的,它所指的贪心算法是不管权重更新是否会对train data有改进都进行修正,因为这里面没有 ...

  5. python笔记-11 rabbitmq

    一.理解rabbitmq的基本背景 1.理解消息队列 1.1 普通queue 在前面的博客中所提到的队列,此处均称之为普通队列 简述一下普通队列的一些分类及不足 1.1.1 基本Queue:queue ...

  6. vs2010 创建和C#使用动态链接库(dll)

    一.VS 用 C++ 创建动态链接库 Step 1:创建Win32 Console Application 本例中我们创建一个叫做“Test”的Solution. Step 2:将Applicatio ...

  7. 一款直接时空处理分析的开源数据库---geomesa

    一款直接时空处理分析的开源数据库---geomesa,可用于交通轨迹数据存储分析等相关领域, 在分布式列数据库的基础上进行扩展,目前支持Accumulo, HBase, Cassandra, and ...

  8. docker windows 2016 安装测试

    1. 安装方式      powershell Install-Module-NameDockerMsftProvider-RepositoryPSGallery-Force Install-Pack ...

  9. 在 FastAdmin 中启动 ThinkPHP 5 的请求缓存分析

    在 FastAdmin 中启动 ThinkPHP 5 的请求缓存分析 缓存的基础配置 ThinkPHP 5 中有一个请求缓存:1 'request_cache' => true, 'reques ...

  10. JavaFX 之窗口大小自由拉伸(四)

    一.问题场景 同样的,隐藏掉窗体的默认标题栏也会导致窗体大小自由拉伸功能的失效. 二.解决思路 判断鼠标在窗体的位置,改变鼠标样式,给窗体组件添加拖拽事件监听器,根据鼠标移动位置改变窗体大小. 三.代 ...