CF1474-D. Cleaning
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的更多相关文章
- 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚
题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ...
- Coursera-Getting and Cleaning Data-week1-课程笔记
博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html -- Sunday, January 11, 2015 课程概述 G ...
- Coursera-Getting and Cleaning Data-Week2-课程笔记
Coursera-Getting and Cleaning Data-Week2 Saturday, January 17, 2015 课程概述 week2主要是介绍从各个来源读取数据.包括MySql ...
- Coursera-Getting and Cleaning Data-Week3-dplyr+tidyr+lubridate的组合拳
Coursera-Getting and Cleaning Data-Week3 Wednesday, February 04, 2015 好久不写笔记了,年底略忙.. Getting and Cle ...
- Coursera-Getting and Cleaning Data-week4-R语言中的正则表达式以及文本处理
博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html Thursday, January 29, 2015 补上第四周笔记,以及本次课程总结. 第四周 ...
- 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划
[BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ...
- poj 2376 Cleaning Shifts
http://poj.org/problem?id=2376 Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- POJ 2376 Cleaning Shifts(轮班打扫)
POJ 2376 Cleaning Shifts(轮班打扫) Time Limit: 1000MS Memory Limit: 65536K [Description] [题目描述] Farmer ...
- POJ 2376 Cleaning Shifts 贪心
Cleaning Shifts 题目连接: http://poj.org/problem?id=2376 Description Farmer John is assigning some of hi ...
- Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题
3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 218 Solved: ...
随机推荐
- 【EXP】exp-00091解决办法
如果遇到exp的话一般都是因为字符集的问题 解决办法: 1.在oracle中查看数据库的字符集 SQL> select userenv('language') from dual; USEREN ...
- Android之Xposed
基础书籍推荐:1.疯狂JAVA讲义:2.疯狂安卓讲义: 逆向分析必须知道他的原理,不然只会用工具,那就直接GG. 谷歌的镜像网站:https://developers.google.com/andro ...
- migo的BAPI示例BAPI_GOODSMVT_CREATE
1 *&---------------------------------------------------------------------* 2 *& Report Z_BAP ...
- 24V降压3.3V芯片,低压降线性稳压器
PW6206系列是一款高精度,高输入电压,低静态电流,高速,低压降线性稳压器具有高纹波抑制.在VOUT=5V&VIN=7V时,输入电压高达40V,负载电流高达300mA,采用BCD工艺制造.P ...
- 针对Fluent-Bit采集容器日志的补充
hello,之前我写过<一套标准的ASP.NET Core容器化应用日志收集分析方案>,在公司团队.微信公众号.Github上反映良好. 其中配置Fluent-bit使用Forward协议 ...
- Golang拼接字符串的5种方法及其效率_Chrispink-CSDN博客_golang 字符串拼接效率 https://blog.csdn.net/m0_37422289/article/details/103362740
Different ways to concatenate two strings in Golang - GeeksforGeeks https://www.geeksforgeeks.org/di ...
- map 传递给函数的代价
https://github.com/unknwon/the-way-to-go_ZH_CN/blob/master/eBook/08.1.md map 传递给函数的代价很小:在 32 位机器上占 4 ...
- OpenSSL 常见对称加密算法特性分析
在选择加密算法,面对一大长串的选项时,大家都有这样的疑问,究竟哪种加密方式是最好的呢? 对于加密方式.算法来说,一般安全性与性能呈负相关,越是安全的,对性能要求则更高. 现在主流的加密协议的安全性均能 ...
- MonkeyScript
MonkeyScript的简单使用 一. 什么是MonkeyScript MS 是官方提供的,除了像猴子一样随机乱点之外,还可以通过编写脚本的形式,完成一系列固定的操作.MS 提供一整套完善的 API ...
- 2020最新idea永久激活教程
注:以下为 idea 最新版本 2020.3.2 的永久激活教程,请按照如下步骤安装激活 (webstorm.pycharm 激活方法相同). 步骤一.下载安装包 去到 idea 官网 https:/ ...