CF1474-D. Cleaning

题意:

给出一个长度为nnn的正整数序列,你可以对序列进行如下操作:

  • 对序列中相邻的两个数字ai,ai+1a_{i}, a_{i+1}ai​,ai+1​同时减去一个数字t(t<=min(ai,ai+1))t(t<=min(a_{i},a_{i+1}))t(t<=min(ai​,ai+1​))。

现在你有一次机会可以将序列中任意两个相邻的数字交换位置(可以不交换)。问你可不可以通过上述操作将序列中所有数字都减为000。


题解:

在说具体做法之前,先考虑三个事情:

1. 先不考虑交换数字,在不交换数字的情况我们要把序列中全部的数字都消为000(当然也可能不能全部消为0)可以通过什么方法呢?可以通过以下两种操作获得:

首先我们假设在a1a_1a1​的前面有一个a0=0a_0=0a0​=0,那么消除的过程就是a1=a1−a0,a2=a2−a1,...,an=an−an−1a_1=a_1-a_0, a_2=a_2-a_1,..., a_n=a_n-a_{n-1}a1​=a1​−a0​,a2​=a2​−a1​,...,an​=an​−an−1​,这样顺利的话就可以把全部的数字消掉。

或者我们假设在ana_nan​的后面有一个an+1=0a_{n+1}=0an+1​=0,那么过程为an=an−an+1,an−1=an−1−an,...,a1=a1−a2a_n=a_n-a_{n+1}, a_{n-1}=a_{n-1}-a_n,..., a_1=a_1-a_2an​=an​−an+1​,an−1​=an−1​−an​,...,a1​=a1​−a2​,同样也可以把全部的数字都消掉。

上述操作为顺利情况下消除的过程,但实际上并不一直是那么的顺利。以上述的第一种操作为例,假如有ai−1>aia_{i-1}>a_{i}ai−1​>ai​,那么就会出现ai<0a_{i}<0ai​<0的情况,这显然是不可能的,同样第二种操作也可能会出现这种情况。

2. 如果从前往后减,那么在交换了ai,ai−1a_{i},a_{i-1}ai​,ai−1​这两个数字之后会不会对ai−1a_{i-1}ai−1​之前的数字造成影响呢?同样的从后往前减,交换ai,ai+1a_{i},a_{i+1}ai​,ai+1​之后会不会对ai+1a_{i+1}ai+1​之后的数字造成影响呢?这两个问题的答案是否定的,均不会造成影响。

3. 对于一个序列,假设现在这个序列可以从前往后把所有数字都消掉,那么先从前往后消掉一部分,那么可不可以从后往前把剩下的一部分全部消掉呢?再假设这个序列不能从前往后或从后往前把全部数字消掉,那么能不能通过先从前往后消掉一部分再从后往前消掉另一部分把整个序列消掉?

换句话说,对于一个序列而言,先从前往后消去一部分,再从后往前消去另一部分,是否和只从前往后或只从后往前消除是等效的呢(能全部消掉或不能)?答案是肯定的,这也是本题的关键。


前面作了那么多铺垫,现在说一下做法。先定义两个数组pre(prefix)pre(prefix)pre(prefix)和suf(suffix)suf(suffix)suf(suffix),pre[i]pre[i]pre[i]表示从前往后消掉了a1,a2,...,ai−1a_{1}, a_{2},..., a_{i-1}a1​,a2​,...,ai−1​之后aia_{i}ai​的值,suf[i]suf[i]suf[i]表示从后往前消掉了an,an−1,...,ai+1a_{n}, a_{n-1},...,a_{i+1}an​,an−1​,...,ai+1​之后a[i]a[i]a[i]的值。这里说一下,不论是从前往后还是从后往前,如果aia_{i}ai​减完之后得到了一个负数,那么他之后的所有数字不论是正是负都没有意义了,所以aia_{i}ai​以及aia_{i}ai​之后所有数字就需要用一个特殊的标记这个preprepre或sufsufsuf是无效的。

现在就可以枚举交换的数字了,比如现在要枚举的是交换aia_{i}ai​和ai+1a_{i+1}ai+1​,那么只需要看pre[i−1],a[i+1],a[i],suf[i+2]pre[i-1],a[i+1],a[i],suf[i+2]pre[i−1],a[i+1],a[i],suf[i+2]这几个数字构成的序列可不可以通过从前往后或者从后往前给全部消掉即可,如果可以答案就是YESYESYES,后面也就不用继续枚举了;如果全部枚举之后都不能那么答案就是NONONO。当然这有个前提就是pre[i−1]pre[i-1]pre[i−1]和suf[i+2]suf[i+2]suf[i+2]不能是无效的,也就是不能是你之前打过特殊标记的。


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>void solve() {int n;scanf("%d", &n);std::vector<int>a(n + 2);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}std::vector<int>pre(n + 2), suf(n + 2);for (int i = 1; i <= n; i++) {if (pre[i - 1] == -1 || a[i] < pre[i - 1]) {pre[i] = -1;} else {pre[i] = a[i] - pre[i - 1];}}if (pre[n] == 0) {printf("YES\n");return;}for (int i = n; i > 0; i--) {if (suf[i + 1] == -1 || a[i] < suf[i + 1]) {suf[i] = -1;} else {suf[i] = a[i] - suf[i + 1];}}for (int i = 0; i <= n - 2; i++) {int l = i, r = i + 3;if (pre[l] == -1 || suf[r] == -1) {continue;}if (a[r - 1] >= pre[l] && a[l + 1] >= suf[r] && a[r - 1] - pre[l] == a[l + 1] - suf[r]) {printf("YES\n");return;}}printf("NO\n");
}int main() {int T;scanf("%d", &T);while(T--) {solve();}return 0;
}

小结:

本题本质上就是暴力,只不过O(n2)O(n^2)O(n2)的暴力是不能接受的,所以先对原来数据进行预处理,使得最终时间复杂度从O(n2)O(n^2)O(n2)减为O(n)O(n)O(n)。

CF1474-D. Cleaning相关推荐

  1. 【BZOJ】1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚(dp/线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1672 dp很好想,但是是n^2的..但是可以水过..(5s啊..) 按左端点排序后 f[i]表示取第 ...

  2. 动态规划 BZOJ1584 [Usaco2009 Mar] Cleaning Up 打扫卫生

    1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 511  Solved: 3 ...

  3. cleaning selected projects has encountered a problem errors occurred during build

    clean 项目的时候出现的问题. cleaning selected projects has encountered a problem errors occurred during build ...

  4. Linux mount: Structure needs cleaning 错误解决方法

    "mount: Structure needs cleaning"报错 可以使用xfs_repair来修复,但是要注意 xfs_repair修复的分区中的文件都会丢失,即使是du能 ...

  5. CF611F. New Year and Cleaning

    CF611F. New Year and Cleaning Solution 还挺巧妙的套路. 把起点整体看作一个矩阵,在操作时移出原来矩阵外的部分的起点都是超越边界的,可以直接通过超出的面积计算贡献 ...

  6. CF1245F Daniel and Spring Cleaning(等会了更新)

    CF1245F Daniel and Spring Cleaning 题意: 给定l,r,求∑a=lr∑b=lr[a+b=a⊕b]\sum_{a=l}^{r}\sum_{b=l}^{r}[a+b=a⊕ ...

  7. 【POJ - 2376】Cleaning Shifts (贪心)

    题干: Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning chores ...

  8. poj 2376 bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班(贪心)

    3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 462  Solved ...

  9. bzoj 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚(DP)

    1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 941  Solved ...

  10. 【安卓学习之常见问题】 使用Eclipse clean时,出现“cleaning all project has encountered a problem”提示

    在使用Eclipse时,经常需要clean下工程,结果每次clean都提示:"cleaning all project has encountered a problem. Errors o ...

最新文章

  1. 2015-01-30工作日记
  2. static成员函数不能调用non-static成员函数
  3. linux 进程 释放内存,Linux 释放内存方法和原理
  4. Multipath多路径冗余全解
  5. Spring Bean装配(上)
  6. 前端基础6:背景常用属性和定位以及BFC
  7. 简单内网映射到公网方法--免费
  8. spring面向接口编程
  9. 支持向量机原理(三)线性不可分支持向量机与核函数
  10. C# WPF中DataGrid的数据绑定(Binding)
  11. 「SAP技术」SAP MM 启用了MPN物料管理的物料,物料主数据与源清单数据有啥不同?
  12. Ubuntu上成功安装永中office2009
  13. Quartus手动生成波形图(以38译码器为例)VHDL
  14. 2022年CISP考试题库下载
  15. python成功安装cartopy之后,调用crs时却出现错误,如何解决
  16. python+tkinter+threading制作多线程简易音乐播放器(自动播放,上一曲,下一曲,播放,暂停,实时显示歌曲名并能自动切换歌曲的功能)
  17. ESP32 天气预报 彩屏
  18. 喜报 |联诚发led球形屏成功入围“深圳企业创新纪录”
  19. C++ 算法篇 动态规划----区间动态规划
  20. 互联网公司晋升利器,只有学会了这些词,你才能在互联网公司混的风生水起!你还不赶紧背下来!

热门文章

  1. pytorch 安装 GPU版本 1030也能装
  2. chmod命令用法详解-chmod修改目录权限
  3. Bonjour CSDN
  4. 国庆去哪玩?用Python爬取了全国5000家旅游景区(记得收藏)
  5. 【学习笔记asp.net】WebService创建、发布及在IIS上部署
  6. 在游戏中如何使用LUA脚本语言
  7. php 数据处理:数组根据某字段进行分组
  8. 小白自学笔记——JAVA基础 1.5API文档说明
  9. 删除Windows AD域控制器的三种方法
  10. mysql从库追主库日志_MySQL 中主库跑太快,从库追不上怎么整?