题目链接 https://www.luogu.com.cn/problem/P2882

分析

这个题来看的话好像有点难下手,不如再去读一遍题 N遍,发现一句话很重要Each time the machine is used, it reverses the facing direction of a contiguous group of K cows in the line,就是说只能翻转固定的长度区间,那这样是不是就可以枚举区间了?枚举一层区间,再枚举每次起点,最后加上区间修改,时间复杂度\(O(N^3)\),肯定会T掉,接下来就考虑优化了。

优化怎么入手呢?时间主要就是出在这三层循环上,只要省掉一层循环,时间复杂度就能到\(O(N^2)\),这样就可以过,第一层循环,显然不能省略,第二层同样,只有在区间修改这一层循环上可以做点手脚,回忆区间修改,有几种做法,线段树,树状数组,还有差分,前两者用在这都有点大材小用或是说不是很合适,因为判断是否区间修改完成不好判断,而差分用在这个区间上就很合适了。那我们大概思路也就有了,首先读入数组,将B标记成1,F标记成0,这里怎么标记都无所谓,然后利用枚举区间,差分修改,最后输出答案,下面考虑一下细节。

我们枚举区间完,要从左到右一次反转区间,为什么呢?题目中要求的是最小次数,就是要先保证次数最小,再考虑区间长度,而我们如果先修改后面的,把后面改好了,再去改前边的,结果一定不会比先改前边的好(有可能相等,如00100),所以我们为保证最小次数,一定从最左端开始依次枚举,如果这个点不符合,就把他后面的整个区间翻转,这里就要用到差分了,肯定直接修改会T掉,我们可以考虑,如果这个区间要修改,那么原来的1会变成2,0会变成1,好像没什么规律,但再看就发现所有的奇数都需要改变,偶数就不用,每次修改给整个区间加一,判断奇偶数就行,然后这就变成了一个区间加一个数的操作,相信大家应该都会。这样修改就完成了,那么怎么判断能不能完成题目的任务呢?由题意可以知道如果当前区间长度小于修改的区间长度,是不能修改的,也就是从n往前的长度为len的区间总是无法被修改的,所以判断这一段区间内有无不满足条件的点即可。

最后找答案的时候也有一个地方,就是当操作修改次数不同时,直接用操作修改次数最小的那个答案就行,但如果当前操作次数和原来答案相同,是不是要考虑一下区间长度改成最小值?答案显然是不是,…………,因为我们是从小到大枚举的区间长度,所以在遇到相等的时候,已经得到的答案的区间长一定是小的,所以只在次数不同时修改答案,但判断上也不会错。

其他优化

当然以下优化不加也没问题,毕竟算法时间复杂度足够过掉这道题。

我做完之后看了看时间大概700ms左右,好像有点高,看别人的时间好像没有特别大,所以我加了加小优化。



为方便说,由上到下一次标号\(1-4\),1,2跑的时间还是挺快的但没啥用,\(NOIp\)不可能给你开O2也不可能给你c++17,所以还是看一下3和4,这俩时间大概有一倍的关系,看一下代码吧

3

#include<cstdio>
#include<cstring>
using namespace std;
const int N=5e3+10;
char s[3];
int cf[N],a[N];
int min(int a,int b){
if(a<b)return a;
else return b;
}
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
if(s[0]=='B')a[i]=1;
else a[i]=0;
}
int res=0x3f3f3f3f,ans=0x3f3f3f3f;
for(int len=1;len<=n;len++){
int cnt=1,k=0;memset(cf,0,sizeof(cf));
for(int i=1;i<=n;i++){
cf[i]+=cf[i-1];
if(i+len-1<=n){
if(a[i]+cf[i]&1){
cf[i]++;cf[i+len]--;k++;
}
}else if(cf[i]+a[i]&1){cnt=0;break;}
}
if(cnt)
if(k<ans){
ans=k;res=len;
}
else if(k==ans)res=min(res,len);
}
printf("%d %d",res,ans);
return 0;
}

4

#include<cstdio>
#include<cstring>
using namespace std;
const int N=5e3+10;
char s[3];
int cf[N],a[N];
int min(int a,int b){
if(a<b)return a;
else return b;
}
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
if(s[0]=='B')a[i]=1;
else a[i]=0;
}
int res=0x3f3f3f3f,ans=0x3f3f3f3f;
for(int len=1;len<=n;len++){
int cnt=1,k=0;memset(cf,0,sizeof(cf));
for(int i=1;i<=n;i++){
cf[i]+=cf[i-1];
if(i+len-1<=n){
if(a[i]+cf[i]&1){
cf[i]++;cf[i+len]--;k++;
}
}else if(cf[i]+a[i]&1)cnt=0;
}
if(cnt)
if(k<ans){
ans=k;res=len;
}
else if(k==ans)res=min(res,len);
}
printf("%d %d",res,ans);
return 0;
}

其实就是少一个break,感觉这个加上还是很有必要的,因为可能极限数据的时候,CCF那评测机状态不好,再卡一下,可能会出问题。

问题

那么有没有可能最开始全部是朝前的呢?答案是没有,英文题面中已经讲到,有一些牛,所以说不可能其实全部朝前边的。

USACO07MAR Face The Right Way G 差分的更多相关文章

  1. [USACO07MAR]Face The Right Way G

    发现选定一个长度后,怎么翻转是固定的. 那我们直接选定一个长度去操作就行. 优化操作过程 类似于堆里打持久化标记一样的感觉. [USACO07MAR]Face The Right Way G // P ...

  2. 洛谷 P2882 [USACO07MAR]Face The Right Way G

    题目传送门 题目描述 Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing ...

  3. luogu P2882 [USACO07MAR]Face The Right Way G

    题目描述 Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing forwar ...

  4. BZOJ3453: tyvj 1858 XLkxc(拉格朗日插值)

    题意 题目链接 Sol 把式子拆开,就是求这个东西 \[\sum_{i = 0} ^n \sum_{j = 1}^{a + id} \sum_{x =1}^j x^k \pmod P\] 那么设\(f ...

  5. BZOJ4650:[NOI2016]优秀的拆分——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 https://www.luogu.org/problemnew/show/P1117 如果 ...

  6. 『题解』[NOI2016]优秀的拆分

    如果一个字符串可以被拆分为\(AABB\)的形式,其中$A和 B是任意非空字符串,则我们称该字符串的这种拆分是优秀的. 例如,对于字符串\(aabaabaa\),如果令\(A=aab\),\(B=a\ ...

  7. CodeChef DGCD Dynamic GCD

    CodeChef题面 Time limit 210 ms Code length Limit //内存限制也不说一下,真是的-- 50000 B OS Linux Language limit C, ...

  8. Storyboards Tutorial 03

    这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...

  9. 文件图标SVG

    ​<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...

随机推荐

  1. 负载均衡框架 ribbon 二

    Ribbon 负载均衡机制 官方文档地址:https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers 1. Ribbon 内置 ...

  2. redis环境搭建及一主二从三哨兵模式配置

    一.单机redis环境搭建 1.安装: OS:linux redhat6.5 下载redis 官网下载链接:https://redis.io/download 把安装包上传到服务器,进行解压 [roo ...

  3. scrapy-redis分布式爬取知乎问答,使用docker布置多台机器。

    先上结果: 问题: 答案: 可以看到现在答案文档有十万多,十万个为什么~hh 正文开始: 分布式爬虫应该是在多台服务器(A B C服务器)布置爬虫环境,让它们重复交叉爬取,这样的话需要用到状态管理器. ...

  4. 浅谈Java中静态代码块和非静态代码块

    静态代码块: static{} 执行优先级高于非静态的初始化块,它会在类初始化(类初始化这个问题改天再详细讨论)的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员. 非静 ...

  5. 深入探索 TCP TIME-WAIT

    1​ TIME-WAIT 状态 主动关闭连接的一方,在四次挥手最后一次发送 ACK 后,进入 TIME_WAIT 状态.在这个状态里,主动关闭连接一方等待 2MSL(Maximum Segment L ...

  6. 题解 NOIP2018【赛道修建】—— 洛谷

    这道题有一点点树上dp的意思(大佬轻喷 我刚拿到这道题的时候毫无头绪,只知道这道题要二分答案 为什么是二分答案??? 题目: 目前赛道修建的方案尚未确定.你的任务是设计一 种赛道修建的方案,使得修建的 ...

  7. 深入解析Underscore.js源码架构

    Underscore.js是很有名的一个工具库,我也经常用他来处理对象,数组等,本文会深入解析Underscore源码架构,跟大家一起学习下他源码的亮点,然后模仿他写一个简单的架子来加深理解.他的源码 ...

  8. niginx:duplicate MIME type "text/html" in nginx.conf 错误(转载)

    把nginx升级到最新以后,发现用原来的配置启动的时候会提示: duplicate MIME type "text/html" in /usr/local/nginx/conf/n ...

  9. 集群搭建_02_集群多机版安装 HDFS HA+Federation-YARN

    1.配置hosts 至少四个节点(机器) 每个节点的hosts文件都要配置这些 10.10.64.226 SY-0217 10.10.64.234 SY-0225 10.10.64.235 SY-02 ...

  10. JavaScript 模式》读书笔记(3)— 字面量和构造函数2

    上一篇啊,我们聊了聊字面量对象和自定义构造函数.这一篇,我们继续,来聊聊new和数组字面量. 三.强制使用new的模式 要知道,构造函数,只是一个普通的函数,只不过它却是以new的方式调用.如果在调用 ...