https://codeforces.com/contest/1236/problem/D

题意:一个n*m格子矩阵,放一个人偶在左上角向右走,只能在每个格子最多右转一次,有k个障碍物。求是否能够一次走完矩阵的所有非障碍物格然后停留在任意位置。

题解:在每个格子最多右转一次,相当于每个格子只能走一次,否则就出不来了。容易想到障碍物必须也是占据一些蛇形的片段,并且留下的位置刚好可以让人偶走一个蛇形的绕到中心,但是怎么判断障碍物的形状呢?百思不得其解遂看题解。题解表示观察到人偶撞墙或者撞障碍物必转向(自己走过的路也是墙)。然后暴力模拟一遍,每次在数据结构里面搜索前进方向上最近的墙/障碍物,走到它面前。至多进行n+m次。

所以选择一个结构就是set,维护行和列分别两堆set,一个障碍物同时插入行列两个set里面。然后墙/自己走过形成的墙就设置一个最值把多走的部分截断就可以了。判断答案的方法就是暴力统计走过的格子数是否等于空格数。

注:实现的时候卡在了样例4,因为会让人偶走回头路,但是也不能够简单让人偶移动0格就退出,比如一条竖线的矩阵。修复的方法是在人偶的后方一个格子塞一个障碍物。然后卡在样例9,看了dalao的代码才知道错在哪里,首先while循环的停止条件错了,不应该是d>u||r>l,应该是d>=u&&r>=l,因为是闭区间。这个改进再加上后面堵一个障碍物就可以防止原路返回了,人偶会在中间不断转圈圈。不过最简单的办法是记录人偶原地不动的次数,>=2次就break掉。

其实并不需要堵格子,记录原地不动的次数之后就不会原路返回了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; set<int> sr[100005], sc[100005]; int main() {
#ifdef KisekiPurin
freopen("KisekiPurin.in", "r", stdin);
#endif // KisekiPurin
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; ++i) {
sr[i].insert(0);
sr[i].insert(m + 1);
}
for(int i = 1; i <= m; ++i) {
sc[i].insert(0);
sc[i].insert(n + 1);
}
for(int i = 1; i <= k; ++i) {
int r, c;
scanf("%d%d", &r, &c);
sr[r].insert(c);
sc[c].insert(r);
} int u = 1, d = n, l = 1, r = m;
int x = 1, y = 1, dir = 1, stay = 0;
ll cnt = 1;
while(d >= u && r >= l) {
if(dir == 1) {///行向右
int ny = min(r, *sr[x].upper_bound(y) - 1);///r是蛇不断走的时候的边界,例如我们第一开始在第一行撞到了阻碍物,那么我们只能右转对吧,那此刻的r边界在下面就更新了,下一次在行里面就不能靠阻碍物位置了而是自己的以该r为边界,因为一个格子不能重复两次
cnt += ny - y;
if(ny == y) {
if(stay == 0)
stay = 1;
else
break;
} else
stay = 0;///如果出现原地踏步两次直接break;
y = ny; //^
++u;//上边界+1,因为该行--------->已经被通过一次了,我们下次|上来的时候是不能碰到这一行的
// |
r = y;
dir = 2;
}
else if(dir == 2) {///列向下
int nx = min(d, *sc[y].upper_bound(x) - 1);
cnt += nx - x;
if(nx == x) {
if(stay == 0)
stay = 1;
else
break;
} else
stay = 0;
x = nx;
--r;
d = x;
dir = 3;
} else if(dir == 3) {///行向左
int ny = max(l, *(--(sr[x].lower_bound(y))) + 1);
cnt += y - ny;
if(ny == y) {
if(stay == 0)
stay = 1;
else
break;
} else
stay = 0;
y = ny;
--d;
l = y;
dir = 4;
} else {///列向上
int nx = max(u, *(--(sc[y].lower_bound(x))) + 1);
cnt += x - nx;
if(nx == x) {
if(stay == 0)
stay = 1;
else
break;
} else
stay = 0;
x = nx;
++l;
u = x;
dir = 1;
}
}
puts((cnt == 1ll * n * m - k) ? "YES" : "NO");
}

  

cf 模拟的更多相关文章

  1. 20190708三人开黑CF模拟赛

    7月8号晚上8点和两位巨佬开了一场虚拟cf: [Helvetic Coding Contest 2018 online mirror (teams allowed, unrated)] 我这么蔡,只A ...

  2. 20190710双人开黑CF模拟赛

    Codeforces Round #571 (Div. 2) 日常被tanao_大佬带飞,我AC了A和C(B题没了...否则tanao_大佬肯定把我吊打) A. Vus the Cossack and ...

  3. Codeforces Round #341 (Div. 2)

    在家都变的懒惰了,好久没写题解了,补补CF 模拟 A - Wet Shark and Odd and Even #include <bits/stdc++.h> typedef long ...

  4. 【CF 676B Pyramid of Glasses】模拟,递归

    题目链接:http://codeforces.com/problemset/problem/676/B 题意:一个n层的平面酒杯金字塔,如图,每个杯子的容量相同.现在往最顶部的一个杯子倒 t 杯酒,求 ...

  5. CF 552(div 3) E Two Teams 线段树,模拟链表

    题目链接:http://codeforces.com/contest/1154/problem/E 题意:两个人轮流取最大值与旁边k个数,问最后这所有的数分别被谁给取走了 分析:看这道题一点思路都没有 ...

  6. cf 443 D. Teams Formation](细节模拟题)

    cf 443 D. Teams Formation(细节模拟题) 题意: 给出一个长为\(n\)的序列,重复\(m\)次形成一个新的序列,动态消除所有k个连续相同的数字,问最后会剩下多少个数(题目保证 ...

  7. CF Soldier and Cards (模拟)

    Soldier and Cards time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  8. CF 319D(Have You Ever Heard About the Word?-模拟)

    D. Have You Ever Heard About the Word? time limit per test 6 seconds memory limit per test 256 megab ...

  9. 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T4(模拟)

    随便模拟下就过了qwq 然后忘了特判WA了QwQ #include <cstdio> #include <algorithm> #include <cstring> ...

随机推荐

  1. 【算法】273-每周一练 之 数据结构与算法(Tree)

    这是第六周的练习题,最近加班比较多. 下面是之前分享的链接: [算法]200-每周一练 之 数据结构与算法(Stack) [算法]213-每周一练 之 数据结构与算法(LinkedList) [算法] ...

  2. 灵魂拷问:如何检查Java数组中是否包含某个值 ?

    在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题.比如说:如何检查Java数组中是否包含某个值 ?像这类灵魂拷问的主题,非常值得深入地研究一下. 另外,我想要告诉大家的是, ...

  3. 3个Spring Boot核心注解,你知道几个?

    Spring Boot 核心注解讲解 Spring Boot 最大的特点是无需 XML 配置文件,能自动扫描包路径装载并注入对象,并能做到根据 classpath 下的 jar 包自动配置. 所以 S ...

  4. 从零开始—Socket系统调用和多态封装

    1 重新搭建实验环境 前面都是用实验楼环境做的实验,偷的懒总是要还的,这一次重装环境前后花了十几个小时,踩了无数的坑. 1.1 Ubuntu和LINUX内核的区别 Ubuntu是基于LINUX内核编写 ...

  5. django基础之day05,F与Q查询,Q查询的高级用法

    #F与Q查询 #*************************** F 查询 ******************** # F 查询数据库中的其他字段!!! #1.查询库存数大于卖出数的书籍 fr ...

  6. THLM,CSS

    目录 HTTP协议的四大特性 数据格式 状态码 HTML概念 标签 标签分类 按是否封闭分类 按级别分类 标签属性 head内常用标签 body内常用标签 body内重要标签 a 标签 img 标签 ...

  7. linux环境下zookeeper下载安装

    步骤一:安装配置jdk环境 1.下载解压jdk-8u221-linux-x64.tar.gz 2.打开 配置文件,vim /etc/profile,添加如下配置,添加完成记得source /etc/p ...

  8. 基于Vue的前后端分离项目实践

    一.为什么需要前后端分离 1.1什么是前后端分离  前后端分离这个词刚在毕业(15年)那会就听说过,但是直到17年前都没有接触过前后端分离的项目.怎么理解前后端分离?直观的感觉就是前后端分开去做,即功 ...

  9. Android4.4 RIL短信接收流程分析

    最近有客户反馈Android接收不到短信,于是一头扎进RIL里面找原因.最后发现不是RIL的问题,而是BC72上报短信的格式不对,AT+CNMA=1无作用等几个小问题导致的.尽管问题不在RIL,但总算 ...

  10. supervisor 相关命令

    今天重新使用 supervisor 相关命令的时候,发现已经忘了,下面重新进行记录一下,进行备忘: supervisorctl restart <application name> ; 重 ...