解题思路

这题思路并不难,主要问题是,不太好编码实现(可能是本人练习不够吧),因为有个时间在里面,而且每个小水滴都同时流动,感觉好复杂的样子。比赛时,我首先想到的是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;
}

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

最新文章

  1. Echarts_1:水平柱体
  2. nginx负载下站点错误响应会导致其他节点重复响应问题的解决过程
  3. this action could not be completed.try again登陆appstore错误提示
  4. JSP的JSTL标签使用
  5. 《Zend studio 12 + UPUPW+PHP5.4开发平台配置过程》
  6. WPF 2D 碰撞检测
  7. 理解RxJava线程模型
  8. 《ASP.NET1200例》ListView 控件与DataPager控件的结合&lt;一&gt;
  9. win下 golang 跨平台编译
  10. Visual Studio Code 1.0.1 for python
  11. Cacti以MB为单位监控流量
  12. STL vector使用方法介绍
  13. 渗透测试工具Nmap从初级到高级
  14. JavaScript 中运算优先级问题
  15. 最长上升子序列(logN算法)
  16. 验证Oracle处理速度
  17. statement preparestatement CallableStatement
  18. Abp vNext 切换MySql数据库
  19. mysql自增长主键,删除数据后,将主键顺序重新排序
  20. call apply bind 区别?

热门文章

  1. TCP的数据传输
  2. Spring报错:java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
  3. java项目添加到Tomcat中运行-(项目转换为Dynamic Web Project)
  4. Scrapy爬虫库使用初体验
  5. 自己总结 C++ 代码规范
  6. 老男孩Linux运维期中架构
  7. Percona 工具 pt-query-digest的使用
  8. MPI 学习
  9. BZOJ3680 吊打XXX 【模拟退火】
  10. iOS 模态框覆盖导航栏