CF1474-D. Cleaning

题意:

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

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

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


题解:

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

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

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

或者我们假设在\(a_n\)的后面有一个\(a_{n+1}=0\),那么过程为\(a_n=a_n-a_{n+1}, a_{n-1}=a_{n-1}-a_n,..., a_1=a_1-a_2\),同样也可以把全部的数字都消掉。

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

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

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

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


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

现在就可以枚举交换的数字了,比如现在要枚举的是交换\(a_{i}\)和\(a_{i+1}\),那么只需要看\(pre[i-1],a[i+1],a[i],suf[i+2]\)这几个数字构成的序列可不可以通过从前往后或者从后往前给全部消掉即可,如果可以答案就是\(YES\),后面也就不用继续枚举了;如果全部枚举之后都不能那么答案就是\(NO\)。当然这有个前提就是\(pre[i-1]\)和\(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(n^2)\)的暴力是不能接受的,所以先对原来数据进行预处理,使得最终时间复杂度从\(O(n^2)\)减为\(O(n)\)。

CF1474-D. Cleaning的更多相关文章

  1. 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚

    题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ...

  2. Coursera-Getting and Cleaning Data-week1-课程笔记

    博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html -- Sunday, January 11, 2015 课程概述 G ...

  3. Coursera-Getting and Cleaning Data-Week2-课程笔记

    Coursera-Getting and Cleaning Data-Week2 Saturday, January 17, 2015 课程概述 week2主要是介绍从各个来源读取数据.包括MySql ...

  4. Coursera-Getting and Cleaning Data-Week3-dplyr+tidyr+lubridate的组合拳

    Coursera-Getting and Cleaning Data-Week3 Wednesday, February 04, 2015 好久不写笔记了,年底略忙.. Getting and Cle ...

  5. Coursera-Getting and Cleaning Data-week4-R语言中的正则表达式以及文本处理

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html Thursday, January 29, 2015 补上第四周笔记,以及本次课程总结. 第四周 ...

  6. 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划

    [BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ...

  7. poj 2376 Cleaning Shifts

    http://poj.org/problem?id=2376 Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. POJ 2376 Cleaning Shifts(轮班打扫)

    POJ 2376 Cleaning Shifts(轮班打扫) Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] Farmer ...

  9. POJ 2376 Cleaning Shifts 贪心

    Cleaning Shifts 题目连接: http://poj.org/problem?id=2376 Description Farmer John is assigning some of hi ...

  10. Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题

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

随机推荐

  1. MyBatis初级实战之六:一对多关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. 深度学习DeepLearning技术实战(12月18日---21日)

    12月线上课程报名中 深度学习DeepLearning(Python)实战培训班 时间地点: 2020 年 12 月 18 日-2020 年 12 月 21日 (第一天报到 授课三天:提前环境部署 电 ...

  3. Spring Security 实战干货:AuthenticationManager的初始化细节

    1. 前言 今天有个同学告诉我,在Security Learning项目的day11分支中出现了一个问题,验证码登录和其它登录不兼容了,出现了No Provider异常.还有这事?我赶紧跑了一遍还真是 ...

  4. Angular入门到精通系列教程(13)- 路由守卫(Route Guards)

    1. 摘要 2. 路由守卫(Route Guards) 2.1. 创建路由守卫 2.2. 控制路由是否可以激活 2.3. 控制路由是否退出(离开) 3. 总结 环境: Angular CLI: 11. ...

  5. 错误捕捉过滤器 .NetCore版

    前言 继承ExceptionFilterAttribute后,重写OnException函数. 统一捕捉所有报错,格式化返回前端. 代码实现 基类控制器 在基类控制器上添加[ErrorCatch]特性 ...

  6. 同步与异步 Python 有何不同?

    你是否听到人们说过,异步 Python 代码比"普通(或同步)Python 代码更快?果真是那样吗? 1 "同步"和"异步"是什么意思? Web 应用 ...

  7. IDEA 简介

    什么是IDEA IDEA 全称 IntelliJ IDEA,是 Java 语言开发的集成环境,IntelliJ 在业界被公认为最好的 Java 开发工具之一,尤其在智能代码助手.代码自动提示.重构.J ...

  8. 。SLI,Service Level Indicator,服务等级指标,其实就是我们选择哪些指标来衡量我们的稳定性。而 SLO,Service Level Objective,服务等级目标,指的就是我们设定的稳定性目标,比如“几个 9”这样的目标。

    .SLI,Service Level Indicator,服务等级指标,其实就是我们选择哪些指标来衡量我们的稳定性.而 SLO,Service Level Objective,服务等级目标,指的就是我 ...

  9. Sapphire: Copying GC Without Stopping the World

    https://people.cs.umass.edu/~moss/papers/jgrande-2001-sapphire.pdf Many concurrent garbage collectio ...

  10. SpringMVC听课笔记(十二:文件的上传)

    1.Spring MVC为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver实现的.Spring用Jakarta Commons FileUpload技术实现了一个M ...