P2882 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 forward, like good cows. Some of them are facing backward, though, and he needs them all to face forward to make his life perfect.
Fortunately, FJ recently bought an automatic cow turning machine. Since he purchased the discount model, it must be irrevocably preset to turn K \((1 ≤ K ≤ N)\) cows at once, and it can only turn cows that are all standing next to each other in line. Each time the machine is used, it reverses the facing direction of a contiguous group of K cows in the line (one cannot use it on fewer than K cows, e.g., at the either end of the line of cows). Each cow remains in the same location as before, but ends up facing the opposite direction. A cow that starts out facing forward will be turned backward by the machine and vice-versa.
Because FJ must pick a single, never-changing value of K, please help him determine the minimum value of K that minimizes the number of operations required by the machine to make all the cows face forward. Also determine M, the minimum number of machine operations required to get all the cows facing forward using that value of K.
N头牛排成一列\(1<=N<=5000\)。每头牛或者向前或者向后。为了让所有牛都 面向前方,农夫每次可以将K头连续的牛转向\(1<=K<=N\),求操作的最少次数M和对应的最小K。
输入格式
Line 1: A single integer: \(N\)
Lines \(2..N+1\): Line \(i+1\) contains a single character, F or B, indicating whether cow \(i\) is facing forward or backward.
第一行一个整数N
第2行至\(N+1\)行是一个字符,F或B,表示向前或向后.
输出格式
Line 1: Two space-separated integers: \(K\) and \(M\)
一行两个数字,\(K\)和\(M\)
输入样例
7
B
B
F
B
F
B
B
输出样例
3 3
题解
很容易想到暴力解法,三层循环,一层枚举\(k\),一层遍历从前往后遍历数组,一遇到向后的牛就一层循环反转后面长度为k的数组,时间复杂度\(O(n^3)\),显然不行,那么就需要优化.
看最后一层循环,可以使用差分优化,每次反转就将次数+1,由于反转两次相当于没有反转,所以就可以根据次数和原本的状态推出反转后的状态.
不需要开一个前缀和数组,因为从前往后遍历,只需要定义一个sum变量存储前缀和,一边累计前缀和一边修改差分数组即可.
代码
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 5010, INF = 1e9;
int n, r, a[maxn], f[maxn];
int check(int k) {
memset(f, 0, sizeof(f));
int sum = 0, ans = 0;
for (int i = 1; i <= n; ++i) {
if (~(a[i] + sum) & 1) { // 如果 a[i] + flag 为偶数
if (i + k - 1 > n) return INF + 1; //超过限制, 返回最大值以保证答案不更新
f[i] ++, f[i + k - 1] --, ans++;
}
sum += f[i];
}
return ans;
}
int main() {
scanf("%d", &n);
char status;
for (int i = 1; i <= n; i++) getchar(), a[i] = getchar() == 'B' ? 0 : 1;
int maxv = INF, ansk = n;
for (int k = 1; k <= n; k++) if ((r = check(k)) <= maxv) maxv = r, ansk = k;
printf("%d %d\n", ansk, maxv);
return 0;
}
附
又到了水的时间
介绍一些我觉得有意思的小技巧,可以让你的代码看起来更简洁难懂
- 判断一个数字奇偶
正常操作自然是模2看结果是0还是1,但是你是否感觉加一个==0或==1太累赘呢?如果想要a为奇数时表达式为真,可以直接使用a%2.如果想要偶数时表达式为真,可以使用!(a%2).
但是后面这个这个又不美观了,要知道if,while等语句的条件也是要加括号的,如果想要偶数时表达式为真,代码可能会变成这样:
if(!(a%2)){
//do something
}
双层括号套一起,太丑了,这时候建议使用位运算,我们要知道一个整数为奇数时,其二进制表示最低位为1,反之为0,那么对这个整数与1取最低位,就可以判断奇偶
如果想要a为奇数时表达式为真,可以使用a&1.如果想要偶数时表达式为真,可以使用~a&1
同样是上面那种情况
if(~a&1){
//do something
}
看起来是不是更清爽让人看不懂了呢?
- 合理使用
getchar()
由于scanf和cin的返回值不是输入值,所以不能直接放在条件表达式里,但是getchar()却不一样,像这种输入字符表示状态的题,可以使用getchar()来获取输入
getchar(), a[i] = getchar() == 'B' ? 0 : 1;
第一个getchar()是读取回车符,然后用三元运算符判断输入,B为0,F为1
- 当条件表达式和语句块内都使用函数返回值
由于当更新答案时,还要执行其它操作,不能用max,min函数,所以需要使用if语句
这里的情况就是
int r=check(k);
if (r <= maxv) maxv = r, ansk = k;
第一行看起来就不爽,想干掉它,但是如果改成:
if (check(k) <= maxv) maxv = check(k), ansk = k;
调用两次函数浪费了时间显然不能选
这时候注意,赋值语句也是有返回值的!其实也能算表达式?
所以你可以这么写(r变量先定义好):
if ((r = check(k)) <= maxv) maxv = r, ansk = k;
P2882 Face The Right Way G 题解的更多相关文章
- 洛谷P3104 Counting Friends G 题解
题目 [USACO14MAR]Counting Friends G 题解 这道题我们可以将 \((n+1)\) 个边依次去掉,然后分别判断去掉后是否能满足.注意到一点, \(n\) 个奶牛的朋友之和必 ...
- 洛谷P2115 Sabotage G 题解
题目 [USACO14MAR]Sabotage G 题解 本蒟蒻又来了,这道题可以用二分答案来解决.我们可以设答案最小平均产奶量为 \(x \ (x \in[1,10000])\) .然后二分搜索 \ ...
- Hdoj 2454.Degree Sequence of Graph G 题解
Problem Description Wang Haiyang is a strong and optimistic Chinese youngster. Although born and bro ...
- P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G 题解
原题链接 POJ的链接 简要题意: 给定一张图,求多少个点,每个点都能到达它. 本题作为强连通分量的入门题. 何为强连通分量?有什么用? 下面一一解释. 首先,我们要确认,这道题目如果不用强连通分量而 ...
- USACO07NOV Cow Relays G 题解
题目 For their physical fitness program, \(N (2 ≤ N ≤ 1,000,000)\) cows have decided to run a relay ra ...
- Codeforces Round #677 (Div. 3) E、G题解
E. Two Round Dances #圆排列 题目链接 题意 \(n\)(保证偶数)个人,要表演一个节目,这个节目包含两种圆形舞蹈,而每种圆形舞蹈恰好需要\(n/2\)个人,每个人只能跳一种圆形舞 ...
- 2018年第九届蓝桥杯【C++省赛B组】B、C、D、F、G 题解
B. 明码 #STL 题意 把每个字节转为2进制表示,1表示墨迹,0表示底色.每行2个字节,一共16行,布局是: 第1字节,第2字节 第3字节,第4字节 .... 第31字节, 第32字节 给定一段由 ...
- [NOI2009] 诗人小G [题解]
诗人小G 题目大意 给出 \(n\) 个长度不超过 \(30\) 的句子,要求你对其进行排版. 对于每一行,有一个规定的行标准长度 \(L\) ,每一行的不协调度等于该行的实际长度与行标准长度差的绝对 ...
- FJUT寒假作业第二周G题解快速幂
题目来源:http://210.34.193.66:8080/vj/Contest.jsp?cid=161#P6 题意:求n个数字的乘积对c取摸.主要就是有快速幂扩展到广义幂的过程. 首先题目 ...
随机推荐
- 利用tcpdump命令统计http的GET和POST请求
1.搭建的知识库服务器, 需要统计来访者都是哪些人,因为系统不是自己开发的,看不到访问日志.所以考虑从系统层面抓取访问流量来实现. 2.通过tcpdump抓取的数据包,在wireshark中打开发现, ...
- HttpUtil工具类,发送Get/Post请求,支持Http和Https协议
HttpUtil工具类,发送Get/Post请求,支持Http和Https协议 使用用Httpclient封装的HttpUtil工具类,发送Get/Post请求 1. maven引入httpclien ...
- @hdu - 6607@ Easy Math Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 求: \[\sum_{i=1}^{n}\sum_{j=1}^{n ...
- Redis学习笔记(二十一) 事务
文章开始啰嗦两句,写到这里共21篇关于redis的琐碎知识,没有过多的写编程过程中redis的应用,着重写的是redis命令.客户端.服务器以及生产环境搭建用到的主从.哨兵.集群实现原理,如果你真的能 ...
- python + selenium登陆并点击百度平台
from PIL import Imagefrom selenium.webdriver import DesiredCapabilitiesfrom selenium import webdrive ...
- 分析ThreadLocal的弱引用与内存泄漏问题
目录 一.介绍 二.问题提出 2.1内存原理图 2.2几个问题 三.回答问题 3.1为什么会出现内存泄漏 3.2若Entry使用弱引用 3.3弱引用配合自动回收 四.总结 一.介绍 之前使用Threa ...
- Windows服务监控工具Perfmon
原文:https://www.jianshu.com/p/f82c2b726ecf 一.Perfmon简介.性能监控指标.性能对象指标 Perfmon:提供了图表化的系统性能实时监视器.性能日志和警报 ...
- Spark文档阅读之二:Programming Guides - Quick Start
Quick Start: https://spark.apache.org/docs/latest/quick-start.html 在Spark 2.0之前,Spark的编程接口为RDD (Resi ...
- C#数据结构与算法系列(五):常见单链表笔试
1.求单链表中有效节点个数 public static int GetLength(HeroNode headNode) { int length = ; var cur = headNode.Nex ...
- 【Flutter实战】图片组件及四大案例
老孟导读:大家好,这是[Flutter实战]系列文章的第三篇,这一篇讲解图片组件,Image有很多高级用法,希望对您有所帮助. 图片组件是Flutter基础组件之一,和文本组件一样必不可少.图片组件包 ...