【题解】洛谷 P9183 [USACO23OPEN] FEB B

2023-12-25 16:28

本文主要是介绍【题解】洛谷 P9183 [USACO23OPEN] FEB B,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 题目描述
      • 输入格式
      • 输出格式
      • 数据范围
      • 知识点
      • 思路
        • 结论
        • 证明
      • 代码


P9183 [USACO23OPEN] FEB B

题目描述

贝西和埃尔希正在密谋最终推翻他们的主人——农夫约翰!他们通过 N N N 条短信进行计划。他们的对话可以用一个长度为 N N N 的字符串 S S S 来表示。
其中 S i S_i Si 是字母 BE,这意味着第 i i i 条消息分别由贝西或埃尔希发送的。

然而,农夫约翰听说了这个消息,并试图拦截他们的谈话。因此,字符串 S S S 的一些字母是 F,这意味着农夫约翰混淆了信息,发件人未知(贝西、埃尔希都有可能)。
注:约翰没有发送信息!他只是在干扰奶牛间的通话!

未混淆对话的兴奋程度是一只奶牛重复发送信息的次数。也就是说,子串 BBEE S S S 中出现的次数。你想找到原始信息的兴奋程度,但你不知道约翰的信息中哪一条实际上是贝西或埃尔希的。在所有可能的情况下,从小到大输出所有可能的兴奋程度。

输入格式

第一行:一个整数 N N N(通话长度)。
第二行:一个字符串 S S S(通话内容)。

输出格式

第一行:输出一个整数 K K K,为不同兴奋程度的可能数量。
随后 K K K 行:每行一个整数,为每种兴奋程度。注意按照从小到大的顺序输出。

数据范围

1 ≤ N ≤ 2 × 1 0 5 1 \le N \le 2 \times 10^5 1N2×105

  • 测试点 4~8: N ≤ 10 N \le 10 N10
  • 测试点 9~20:无额外限制。

知识点

DFS、找规律、贪心。

思路

结论

通过 DFS 暴力对拍,我们发现答案为一个等差数列。

证明

不妨设整个序列中仅有一个 F

分类讨论这个 F 的位置。

  1. F 在开头

此时序列形如 Fxxxxxx

不妨设第二位为 E

  • 若将 F 变为 E,则对答案的贡献为 1 1 1

  • 若将 F 变为 B,则对答案无贡献。

  1. F 在中间

此时序列形如 xxxFxxx

  • F 两侧字符相同。不妨设该字符为 E,则序列为 xxEFExx

    • 若将 F 变为 E,则对答案的贡献为 2 2 2

    • 若将 F 变为 B,则对答案无贡献。

  • F 两侧字符不同。不妨设此时序列为 xxBFExx。无论如何替换,对答案的贡献都是 1。因此下面进行贪心时不考虑这种情况。

  1. F 在结尾。这种情况与情况 1 1 1F 在开头)相同。

证毕。得出结论:答案为一个等差数列,且如果字符串首尾至少一个位置是 F,那么等差数列的公差为 1 1 1。如果头和尾都不是 F,那么等差数列公差为 2 2 2


对于中间的 F,我们考虑贪心求出等差数列首项与末项。

发现 EB 交替放置时方案数最小,即为数列首项。

同理,相邻的 EB 尽量相同时,方案数最大,即为数列末项。

代码

#include <iostream>
#include <cstring>using namespace std;const int N = 300010;int n, hh, tt;
char s1[N], s2[N];int main()
{int sub = 0, hh = 0, tt = 0; // 公差、首项、末项scanf("%d%s", &n, s1);if (s1[0] == 'F' || s1[n - 1] == 'F') sub = 1; // 首尾 -> 公差为 1else sub = 2; // 否则公差为 2while (tt < n - 1 && s1[tt] == 'F') tt ++ ; // 找到第一个不是 F 的位置开始贪心for (int i = 0; i < n; i ++ ) s2[i] = s1[i];for (int i = tt + 1; i < n; i ++ ){if (s1[i] == 'F'){s2[i] = s2[i - 1]; // 最小值尽量相等if (s1[i - 1] == 'E') s1[i] = 'B'; // 最大值尽量交替出现if (s1[i - 1] == 'B') s1[i] = 'E';}if (s1[i] == s1[i - 1]) hh ++ ; // 向首项末项累加答案if (s2[i] == s2[i - 1]) tt ++ ;}int k = (tt - hh) / sub + 1; // 计算等差数列项数printf("%d\n", k);for (int i = hh; i <= tt; i += sub)printf("%d\n", i);return 0;
}

这篇关于【题解】洛谷 P9183 [USACO23OPEN] FEB B的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/536157

相关文章

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

P2858 [USACO06FEB] Treats for the Cows G/S 题解

P2858 题意 给一个数组。每天把最左或者最右的东西卖掉,第 i i i个东西,第 d a y day day天卖出的价格是 a [ i ] ∗ d a y a[i]*day a[i]∗day。 记忆化搜索 void dfs(int l,int r,int day,ll sum){if(v[l][r]>=sum)return;v[l][r]=sum;if(l>r)//这就是dp答案{

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=

洛谷 凸多边形划分

T282062 凸多边形的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 先整一个半成品,高精度过两天复习一下补上 #include <iostream>#include <algorithm>#include <set>#include <cstring>#include <string>#include <vector>#include <map>

能量项链,洛谷

解释:  环形dp问题还是考虑将环拉直,可以参考我上一篇文章:环形石子合并 [2 3 5 10 2] 3 5 10 将环拉直,[]内是一个有效的区间,可以模拟吸收珠子的过程,         如[2 3 5] <=>(2,3)(3,5)    2是头,3是中间,5是尾 len >= 3:因为最后[2 10 2]是最小的可以合并的有效区间 len <= n + 1因为[2 3