题目链接 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. JavaScript,ajax与springboot之间的传参方式

    Springboot:@PostMapping("/mDelTest")public String mDelTest (@RequestBody List<String> ...

  2. CF 1305E. Kuroni and the Score Distribution

    题目大意:题目给定两个数n和m(1<=n<=5000,0<=m<=1e9)要求构造一个数列A,A中元素 大于等于1,小于等于1e9且满足严格递增 满足ai+aj=ak的(i,j ...

  3. flask前端上传图片/文件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Element-UI饿了么时间组件控件按月份周日期,开始时间结束时间范围限制参数

    在日常开发中,我们会遇到一些情况,在使用Element-UI 限制用户的日期时间范围的选择控制(例如:查询消息开始和结束时间,需要限制不能选择今天之后的时间). 看了网上的一些文档,零零散散.各式各样 ...

  5. 第八章、小节三keep-alive

    主要缓存的是ajax中的json 我的路由中的内容被加载过一次,我就把路由中的内容放到内存中,下次再进入这个路由的时候,不需要重新加载页面,直接从内存中获取数据. 切换不同城市,调用不同城市数据 但是 ...

  6. vue的子组件不能进行router的切换

    在用vue开发过程中,偶然一次使用在子组件中进行router的切换,发现不起作用,后来才反应过来,子组件只是一个组件,vue的路由的切换只能是在父组件(也就是真正的页面)里面进行跳转!

  7. html5 拖放购物车

    1.本例中模仿了购物车添加的功能 主要运用了ondragstart / ondragover/ ondrag 功能 功能比较简单 遗留问题:火狐下图片拖进会被打开 <!doctype html& ...

  8. 原生Canvas循环滚动弹幕(现金红包活动带头像弹幕)

    效果 gif有些糊,可以 在线预览 实现关键点 requestAnimationFrame 循环帧: 绘制单条弹幕,画框子 -> 画头像 -> 写黑色的字 -> 写红色的字, mea ...

  9. Open live Writer 直接发布wps文章,优点是可以带上图片

    官方网站: http://openlivewriter.org/ 博客园的设置里面的 MetaWeblog访问地址

  10. rpc框架dubbo学习入门及环境搭建(spring boot+Kotlin)

    学习之前,确保有以下知识基础: Java网络编程 Socket传输数据 IO流 rpc简介及实现 rpc是remote procedure call的简写,意思为远程过程调用. rpc应用较多的情景是 ...