题目链接 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. 7-1 jmu-python-汇率兑换 (10 分)

    7-1 jmu-python-汇率兑换 (10 分)   按照1美元=6人民币的汇率编写一个美元和人民币的双向兑换程序 输入格式: 输入人民币或美元的金额,人民币格式如:R100,美元格式如:$100 ...

  2. 一篇带你看懂Flutter叠加组件Stack

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 Stack Stack组件可以将子组件叠加显示,根据子组件 ...

  3. 《数字信号处理》课程实验2 – FIR数字滤波器设计

    一.FIR数字滤波器设计原理  本实验采用窗函数法设计FIR数字低通滤波器.我们希望设计的滤波器系统函数如下: \(H_{d}\left( e^{jw} \right) = \left\{ \begi ...

  4. Yuchuan_Linux_C编程之一 Vim编辑器的使用

    一.整体大纲 二.Vim 编辑器的使用 vi -- vim    vim是从vi发展过来的一款文本编辑器    vi a.txt    前提: 安装了vim软件 工作模式: 1. 命令模式 -- 打开 ...

  5. 峰哥说技术:08-Spring Boot整合FreeMarker视图

    Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 08  峰哥说技术:Spring Boot整合FreeMarker视图 前面带着大家整合了Thymelea ...

  6. 看逐浪CMS技术小哥做SVG动画(附使用Bodymovin和Lottie将Adobe After Effects(AE)程式转为 HTML5/Android/iOS原生的动画全过程-即AE转svg\canvas\html5动画)

      名词解解释 adobe After Effects AE:adobe After Effects,adobe公司的专业视频制作软件. Bodymovin插件预览 Bodymovin:是一个AE的插 ...

  7. 安装部署hyperledger fabric1.0

    安装环境 CentOS7 1.安装Docker Docker Hub在国外,安装会较慢,可用国内镜像DaoCloud.可执行以下命令安装Docker. sudo yum install -y yum- ...

  8. iNeuOS工业互联平台,开放设备驱动管理、服务驱动管理、云组态自定义画布等,促进平台开放、赋能和落地。发布:v2.3版本。

    目       录 1.      概述... 2 2.      iNeuOS平台演示... 2 3.      设备驱动管理... 2 4.      服务驱动管理... 3 5.      云组 ...

  9. 前后端分离项目采用Prerender的SEO优化流程

    原文: https://blog.ccyws.cn/articles/4 一.概述 近年开发模式变化,新建Web站点采用前后端分离部署已经是大势所趋.但是,搜索引擎爬虫不会执行js脚本从后端加载数据, ...

  10. ASP.net MVC 构建layui管理后台(整体效果)

    登录页: 首页 模块管理 角色管理,角色分配 用户管理