[atARC112E]Rvom and Rsrev
毒瘤分类讨论题
(注:以下情况都有“之前的情况都不满足的”前提条件,并用斜体表示一些说明)
Case0:若$|s|\le 2$,直接输出即可,因此假设$|s|>3$
首先,我们最希望在不对$b$操作的前提下(不减小$b$的数量)使得所有$b$都在最前面,此时即最大化后缀$a$的数量,由于每一次操作减少两个$a$,即最小化操作数
Case1:以$a$为结尾(不难证明此时总是可以达到我们最希望的情况)
Case1.1:以$aa$为结尾,将$a$通过$b$划分为若干个非空段,根据长度分为两类:
1.对于非结尾且长度大于1的段,将该段第一个$a$与结尾段的第一个$a$操作,每一段多1次操作
2.对于(非结尾且)长度为1的段,与同类的段相互抵消,需要段数除以2上取整次操作
Case1.2:以$ba$为结尾,同样将其划分后,再分类讨论
Case1.2.1:若不存在长度大于2的段,则永远无法使得最终结尾$a$的个数大于1,因此最终个数取决于初始$a$个数的奇偶性(即0或1)
Case1.2.2:无特殊限制(存在长度大于2的段),将该段第一个$a$与结尾的$a$操作后,即与Case1.1相同
事实上,由于恰好不考虑最后一段$a$以及每一段$a$都要一次操作,所以与Case1.1完全相同
Case2:$a$的个数为偶数,此时直接成对来删除所有$a$即可
如果不满足Case1和Case2,那么是达不到最希望的情况的,此时根据是否对$b$操作来分类
对$b$操作的基本思路是将末尾的$b$与一个$a$之前的$b$操作使得以$a$为结尾,那么至少要损失两个$b$,同时能够做到让剩下的$b$都在最前面
Case3:整个字符串中不存在形如$ba$的形式,或以$abb$、$ab$结尾
此时选择不对$b$操作,显然保留最后的$a$,将其余$a$成对消除即可
Case4:无特殊条件(不满足Case1、Case2和Case3)
Case4.1:不以$a$为开头
注意到与长度大于1的段之前的$b$操作一定会使得答案减小2,而与长度为1的段之前的$b$操作至多使答案减小2,因此显然与长度大于1的段之前的$b$操作
Case4.1.1:不存在长度大于1的段,那么与Case1.2.1相同,最终结尾的$a$个数即初始$a$个数奇偶性
Case4.1.2:存在长度大于1的段,将末尾的$b$与该段开头的$b$操作后与Case1.1相同
Case4.2:以$a$为开头
Case4.2.1:以$ab$为开头或存在不在开头且长度大于1的段,此时与Case4.1同样操作即可
Case4.2.2:无特殊限制(以$aa$为开头且不存在不在开头且长度大于1的段),此时先将末尾的$b$与任意一个$a$之前的$b$(长度都是1)操作,之后与Case1.2相同
先将开头的$a$与某一个$a$操作是等价的,此时对应于Case4.1


- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 int t;
- 4 char s[200005];
- 5 int main(){
- 6 scanf("%d",&t);
- 7 while (t--){
- 8 scanf("%s",s);
- 9 int n=strlen(s),tot=0;
- 10 if (n<=2){//Case0
- 11 printf("%s\n",s);
- 12 continue;
- 13 }
- 14 for(int i=0;i<n;i++)
- 15 if (s[i]=='a')tot++;
- 16 if (s[n-1]=='a'){//Case1
- 17 for(int i=0;i<n-tot;i++)printf("b");
- 18 int one=0,sum=0;
- 19 if (s[n-2]=='a'){//Case1.1
- 20 for(int i=0;i<n;i++)
- 21 if ((s[i]=='a')&&(i<n-1)&&(s[i+1]=='b')){
- 22 if ((!i)||(s[i-1]=='b'))one++;
- 23 else sum++;
- 24 }
- 25 sum+=(one+1)/2;
- 26 for(int i=0;i<tot-2*sum;i++)printf("a");
- 27 printf("\n");
- 28 continue;
- 29 }
- 30 //Case1.2
- 31 bool flag=0;
- 32 for(int i=0;i<n-2;i++)
- 33 if ((s[i]=='a')&&(s[i+1]=='a')&&(s[i+2]=='a'))flag=1;
- 34 if (!flag){//Case1.2.1
- 35 if (tot&1)printf("a");
- 36 printf("\n");
- 37 continue;
- 38 }
- 39 for(int i=0;i<n;i++)
- 40 if ((s[i]=='a')&&(i<n-1)&&(s[i+1]=='b')){
- 41 if ((!i)||(s[i-1]=='b'))one++;
- 42 else sum++;
- 43 }
- 44 sum+=(one+1)/2;
- 45 for(int i=0;i<tot-2*sum;i++)printf("a");
- 46 printf("\n");
- 47 continue;
- 48 }
- 49 if (tot%2==0){//Case2
- 50 for(int i=0;i<n-tot;i++)printf("b");
- 51 printf("\n");
- 52 continue;
- 53 }
- 54 int flag=0,las=-1;
- 55 for(int i=1;i<n;i++)
- 56 if ((s[i-1]=='b')&&(s[i]=='a'))flag=1;
- 57 for(int i=0;i<n;i++)
- 58 if (s[i]=='a')las=i;
- 59 if ((!flag)||(las>=n-3)){//Case3
- 60 for(int i=0;i<las;i++)
- 61 if (s[i]=='b')printf("b");
- 62 printf("a");
- 63 for(int i=las+1;i<n;i++)
- 64 if (s[i]=='b')printf("b");
- 65 printf("\n");
- 66 continue;
- 67 }
- 68 //Case4
- 69 for(int i=0;i<n-tot-2;i++)printf("b");
- 70 if (s[0]!='a'){//Case4.1
- 71 bool flag=0;
- 72 for(int i=0;i<n-1;i++)
- 73 if ((s[i]=='a')&&(s[i+1]=='a'))flag=1;
- 74 if (!flag){//Case4.1.1
- 75 if (tot&1)printf("a");
- 76 printf("\n");
- 77 continue;
- 78 }
- 79 //Case4.1.2
- 80 int one=0,sum=-1;
- 81 for(int i=0;i<n;i++)
- 82 if ((s[i]=='a')&&(i<n-1)&&(s[i+1]=='b')){
- 83 if ((!i)||(s[i-1]=='b'))one++;
- 84 else sum++;
- 85 }
- 86 sum+=(one+1)/2;
- 87 for(int i=0;i<tot-2*sum;i++)printf("a");
- 88 printf("\n");
- 89 continue;
- 90 }
- 91 //Case4.2
- 92 flag=0;
- 93 for(int i=0;i<n-1;i++){
- 94 if ((s[i]=='b')&&(!flag))flag=1;
- 95 if ((flag)&&(s[i]=='a')&&(s[i+1]=='a'))flag=2;
- 96 }
- 97 if ((s[1]=='b')||(flag>1)){//Case4.2.1
- 98 bool flag=0;
- 99 for(int i=0;i<n-1;i++)
- 100 if ((s[i]=='a')&&(s[i+1]=='a'))flag=1;
- 101 if (!flag){
- 102 if (tot&1)printf("a");
- 103 printf("\n");
- 104 continue;
- 105 }
- 106 int one=0,sum=-1;
- 107 for(int i=0;i<n;i++)
- 108 if ((s[i]=='a')&&(i<n-1)&&(s[i+1]=='b')){
- 109 if ((!i)||(s[i-1]=='b'))one++;
- 110 else sum++;
- 111 }
- 112 sum+=(one+1)/2;
- 113 for(int i=0;i<tot-2*sum;i++)printf("a");
- 114 printf("\n");
- 115 continue;
- 116 }
- 117 //Case4.2.2
- 118 if ((s[0]!='a')||(s[1]!='a')||(s[2]!='a')){
- 119 if (tot&1)printf("a");
- 120 printf("\n");
- 121 continue;
- 122 }
- 123 int one=-1,sum=0;
- 124 for(int i=0;i<n;i++)
- 125 if ((s[i]=='a')&&(i<n-1)&&(s[i+1]=='b')){
- 126 if ((!i)||(s[i-1]=='b'))one++;
- 127 else sum++;
- 128 }
- 129 sum+=(one+1)/2;
- 130 for(int i=0;i<tot-2*sum;i++)printf("a");
- 131 printf("\n");
- 132 }
- 133 }
[atARC112E]Rvom and Rsrev的更多相关文章
- 【BZOJ3506】【Cqoi2014】排序机械臂
传送门(因为BZOJ上没有题面...所以放的是luogu的) 题意:你需要维护一个序列,支持区间翻转与查询区间最小. 解题思路:由于区间最小实际上每一次就是对应的整个数列的第k小,因此可以直接预处理解 ...
- 【BZOJ1500】【Noi2005】维修数列
题意原题很清楚了. 解题思路:裸的平衡树操作,注意动态开点即可. 细节还是比较多的,具体参见代码吧... #include <stdio.h> #include <algorithm ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- Android控件——Button与ImageButton
1.简单介绍
- C++ 全面刨析使用指针方法 _new _delete
指针 #include<iostream> using namespace std; int main() { ; int* pn;//声明 int* pn = &avr;//初始 ...
随机推荐
- 如何基于Jupyter notebook搭建Spark集群开发环境
摘要:本文介绍如何基于Jupyter notebook搭建Spark集群开发环境. 本文分享自华为云社区<基于Jupyter Notebook 搭建Spark集群开发环境>,作者:apr鹏 ...
- 利用OpenCV存储一段视频中的每一帧
// vfc.cpp : 定义控制台应用程序的入口点.#include "stdafx.h"#include <opencv2/highgui/highgui.hpp> ...
- 5 大场景深度探讨何为 Serverless 架构模式?
作者 | Hongqi 阿里云高级技术专家 究竟什么是 Serverless 架构? 什么是 Serverless 架构?按照 CNCF 对 Serverless 计算的定义,Serverless 架 ...
- GDP区域分布图的生成与对比(ArcPy实现)
一.背景 各地区经济协调发展是保证国民经济健康持续稳定增长的关键.GDP是反映各地区经济发展状况的重要指标.科学准确分析各地区GDP空间分布特征,对制定有效措施,指导经济协调发展具有重要参考价值. 二 ...
- 洛谷4366——最短路(dijkstra,思维,异或)
题目大意 给定一个n个点,m条边的图,每条边有边权,而每个点\(i\)也可以直接到达\(j\),代价是\(i\ xor\ j\),给定一个S和T,求S到T的最小代价 其中\(n\le100000,m\ ...
- FastAPI 学习之路(十二)接口几个额外信息和额外数据类型
系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...
- 2021.3.10--vj补题
B - Saving the City cf--1443B Bertown is a city with nn buildings in a straight line. The city's sec ...
- pycharm中安装和使用sqlite过程详解
创建Django项目,添加app 使用虚拟环境 项目创建默认使用的Django数据库是sqlite 配置静态文件 STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀 S ...
- 2020年OO助教工作总结
随着这学期课程的落幕,我一学期的OO助教工作也宣告结束.这学期我的工作主要在系统组,和OO后台的数据库打交道. 作业查重 我几乎每周都会做的例行工作,是对每周的homework进行查重管理.由于使用了 ...
- gson中TypeAdapter实现自定义序列化操作
最近在项目中遇到这么一个问题,我们后台需要向前端返回一个 json 数据,就是将一个地理位置对象以json的格式返回到前台,但是这个地理位置对象中的经纬度是Double数据类型,项目中规定,如果经纬度 ...