题目

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;
}

附

又到了水的时间

介绍一些我觉得有意思的小技巧,可以让你的代码看起来更简洁难懂

  1. 判断一个数字奇偶

正常操作自然是模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
}

看起来是不是更清爽让人看不懂了呢?

  1. 合理使用getchar()

由于scanf和cin的返回值不是输入值,所以不能直接放在条件表达式里,但是getchar()却不一样,像这种输入字符表示状态的题,可以使用getchar()来获取输入

getchar(), a[i] = getchar() == 'B' ? 0 : 1;

第一个getchar()是读取回车符,然后用三元运算符判断输入,B为0,F为1

  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 题解的更多相关文章

  1. 洛谷P3104 Counting Friends G 题解

    题目 [USACO14MAR]Counting Friends G 题解 这道题我们可以将 \((n+1)\) 个边依次去掉,然后分别判断去掉后是否能满足.注意到一点, \(n\) 个奶牛的朋友之和必 ...

  2. 洛谷P2115 Sabotage G 题解

    题目 [USACO14MAR]Sabotage G 题解 本蒟蒻又来了,这道题可以用二分答案来解决.我们可以设答案最小平均产奶量为 \(x \ (x \in[1,10000])\) .然后二分搜索 \ ...

  3. Hdoj 2454.Degree Sequence of Graph G 题解

    Problem Description Wang Haiyang is a strong and optimistic Chinese youngster. Although born and bro ...

  4. P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G 题解

    原题链接 POJ的链接 简要题意: 给定一张图,求多少个点,每个点都能到达它. 本题作为强连通分量的入门题. 何为强连通分量?有什么用? 下面一一解释. 首先,我们要确认,这道题目如果不用强连通分量而 ...

  5. USACO07NOV Cow Relays G 题解

    题目 For their physical fitness program, \(N (2 ≤ N ≤ 1,000,000)\) cows have decided to run a relay ra ...

  6. Codeforces Round #677 (Div. 3) E、G题解

    E. Two Round Dances #圆排列 题目链接 题意 \(n\)(保证偶数)个人,要表演一个节目,这个节目包含两种圆形舞蹈,而每种圆形舞蹈恰好需要\(n/2\)个人,每个人只能跳一种圆形舞 ...

  7. 2018年第九届蓝桥杯【C++省赛B组】B、C、D、F、G 题解

    B. 明码 #STL 题意 把每个字节转为2进制表示,1表示墨迹,0表示底色.每行2个字节,一共16行,布局是: 第1字节,第2字节 第3字节,第4字节 .... 第31字节, 第32字节 给定一段由 ...

  8. [NOI2009] 诗人小G [题解]

    诗人小G 题目大意 给出 \(n\) 个长度不超过 \(30\) 的句子,要求你对其进行排版. 对于每一行,有一个规定的行标准长度 \(L\) ,每一行的不协调度等于该行的实际长度与行标准长度差的绝对 ...

  9. FJUT寒假作业第二周G题解快速幂

    题目来源:http://210.34.193.66:8080/vj/Contest.jsp?cid=161#P6     题意:求n个数字的乘积对c取摸.主要就是有快速幂扩展到广义幂的过程. 首先题目 ...

随机推荐

  1. @Ajax.ActionLink跳转页面的问题解决方案 MVC Ajax不支持问题

    [JavaScriptResult]在客户端执行服务器返回的JavaScript代码当一个内置的Ajax辅助方法请求一个操作方法,该方法会返回一个在客户端执行立即的脚本. public ActionR ...

  2. 我去,你竟然还不会用 Java final 关键字

    写一篇文章容易吗?太不容易了,首先,需要一个安静的环境,这一点就非常不容易.很多小伙伴的办公室都是开放式的,非常吵,况且上班时间写的话,领导就不高兴了:只能抽时间写.其次,环境有了,还要有一颗安静的心 ...

  3. const修饰this指针的用法

    #include <iostream> #include <string> using namespace std; class Base { }; class Excepti ...

  4. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  5. CentOS Linux release 7.7.1908 (Core)--rabbitmq用户创建以及相关防火墙端口开启问题

    增加访问用户,默认用户guest只能本地访问. #添加用户 rabbitmqctl add_user 账号 密码 rabbitmqctl add_user admin admin #分配用户标签(ad ...

  6. Adobe Photoshop CC 2019 下载+安装教程

    1. 安装包 链接: https://pan.baidu.com/s/1_w1SjGVjWNJ9nuTqEcaykg 提取码: xatq 2. 打开安装包 运行Set-up,选择语言,位置 ,选择继续 ...

  7. 多语言工作者の十日冲刺<3/10>

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺--第三天(05.02) 作业正文 ...

  8. 上海开发票/v电13543443967

    关于事项:Iㄋ5一★4З44一★ㄋ9.б7开发票的准备资料必须要公司名称个人的话就用个人名字和身份证去税务柜台申请办理!公司的话要提供公司全称就是营业执照上的名称,纳税人税号,如果是开普通增值税发票的 ...

  9. 关于HTTP 请求方式: GET和POST的比较的本质

    什么是HTTP? 超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议. HTTP在客户端和服务器之间以request ...

  10. JDK开发环境的搭建和环境变量的配置

    首先博主先说一下JDK.JRE.JVM的区别和联系.我们正常运行程序的话只需安装JRE就行啦,如果要编译运行Java程序就得需要JKD下的bin目录下的编译工具. JDK -- java develo ...