[CSP-S模拟测试]:寿司(暴力)
题目描述
小$c$是一名$oier$。最近,他发现他的数据结构好像学傻了。因为他在刷题时碰到了一道傻逼数据结构题,强行使用了平衡树来解决,卡着时间$AC$。为此,他被狠狠地嘲讽了一番。于是,小$c$找了大量的数据结构题来做。
昨天,小$c$正在吃寿司,突然发现许多盘寿司围成了一个圆圈,这些寿司中有红色的也有蓝色的。由于小$c$看交错的颜色非常不爽,想通过一些操作,使得所有的红色寿司形成了一块连续的区域,蓝色的寿司也形成了一块连续的区域。如果小$c$每次只可以交换相邻的两盘寿司,那么最少需要多少步才可以达到小$c$的要求呢?由于他做题做多了,脑袋已经有点不清醒了,于是这个问题就交给你了。
输入格式
第一行一个数$T$,表示数据组数。
接下来$T$行,每行一行由$B$和$R$组成的字符串,$B$表示蓝色,$R$表示红色。第$i$个字符描述顺时针数第$i$盘寿司的颜色。注意,最后一盘寿司和第$1$盘寿司是相邻的。
输出格式
对于每组数据,输出一行表示最小的交换次数。
样例
样例输入
1
BBRBBRBBBRRR
样例输出
5
数据范围与提示
样例说明:
以下说明交换的步骤:
交换位置$2$、位置$3$上的寿司;
交换位置$1$、位置$2$上的寿司;
交换位置$6$、位置$7$上的寿司;
交换位置$7$、位置$8$上的寿司;
交换位置$8$、位置$9$上的寿司;
数据范围:
$T\leqslant 10$
$n\leqslant 1,000,000$
题解
算法一:
爆搜,枚举所有走法。可以获得$0$到$20$分不等。
算法二:
注意到每种状态实际上是可以压缩的。所以搜索的时候对于较小的数据把状态记录下来,用最小表示法去个重,对于稍大的数据可以用$IDA∗$搜索,对每个状态进行估价来进行加速。可以获得$20$到$40$分不等。
算法三:
将环上的问题转化为序列上,我们只需要将环复制一遍即可转化为序列。
那么,考虑这样一个问题,对于最优解,一定存在一个点使得所有的交换都不经过这个点(它的左右不交换),下面简称这个点为断点。
这样我们就可以枚举断点,答案即为把每个$B$挪到两端,反之同理。
然后在进行统计答案,比较每一个断点哪个最优。
现在来简单的证明一下断点的存在,来脑补一个环,环上面有很多$R$,我们肯定要将所有的$R$都撸到一起,而这时候,肯定存在“最下面一个点”作为底端,而在撸的时候肯定不会经过这个点。
时间复杂度:$\Theta (n^2)$。
期望得分:$40$分。
算法四:
考虑决策的单调性问题,上面$\Theta (n^2)$的算法中,我们需要再枚举一个点,这个点左端的$R$都移向左端,右端的都移向右端,那么就满足了一个$\bigcup$型函数。
显然可以进行三分求解。
那么当前枚举的区间的代价怎么求呢?
我们需要开五个数组:
$\alpha.slft[i]$:表示将点$i$左侧所有的$R$都挪到最左端所要付出的代价,而每个$R$挪到最左端的代价就是它左端的$B$的数量。
$\beta.srht[i]$:表示将点$i$右侧所有的$R$都挪到最右端所要付出的代价。
$\chi.blft[i]$:表示点$i$左侧有几个$B$,可以感性的理解为$B$的左缀和。
$\delta.brht[i]$:表示点$i$右侧有几个$B$,可以感性的理解为$B$的右缀和。
$\epsilon.rlft[i]$:表示点$i$左侧有几个$R$,可以感性的理解为$R$的前缀和。
下面我只讲当前区间$[L,R]$下,将点$V$左侧的$R$都移到$L$所要付出的代价,反之同理:
先写出来式子:$slft[V]-slft[L-1]-blft[L-1]\times (rlft[V]-rlft[L-1])$。
来解释一下式子:
$slft[V]-slft[L-1]$的含义为将$[L,V]$区间中所有的$R$移到最左端所要付出的代价,不过显然我们并不用把他们都移到左端,而是将其移动到$L$,那么我们不需要付出的代价就为$1$到$L$之间的$B$乘上$L$到$V$之间的$R$,即为$blft[L-1]\times (rlft[V]-rlft[L-1])$。
时间复杂度:$\Theta (n\log_{\frac{3}{2}}n)$。
期望得分:$65$分。
算法五:
我们还会发现这样一个问题,在断点不断右移的时候,当前状态的最有决策点肯定在上衣状态的最优决策点的右侧,这样复杂度就成了线性的了。
时间复杂度:$\Theta (n)$。
期望得分:$100$分。
代码时刻
$\Theta (n\log_{\frac{3}{2}}n)$算法:
#include<bits/stdc++.h>
using namespace std;
int n;
char ch[4000001];
long long slft[4000001],srht[4000001],blft[4000001],brht[4000001],rlft[4000001];
long long ans;
long long minn(int x,int y,int z){return min(x,min(y,z));}
long long judge(int l,int v,int r)
{return slft[v]-slft[l-1]-blft[l-1]*(rlft[v]-rlft[l-1])+srht[v+1]-srht[r+1]-brht[r+1]*(rlft[r]-rlft[v]);}//计算答案
long long _doudou(int l,int r)//三分
{
int flagl=l,flagr=r;
while(r-l>2)
{
int midl=(r-l+1)/3+l;
int midr=(r-l+1)*2/3+l;
if(judge(flagl,midl,flagr)>judge(flagl,midr,flagr))l=midl;
else r=midr;
}
return minn(judge(flagl,l+1,flagr),judge(flagl,l,flagr),judge(flagl,r,flagr));
}
void pre_work()//清空
{
for(int i=1;i<=n;i++)ch[n+i]=ch[i];
blft[0]=slft[0]=rlft[0]=srht[2*n+1]=brht[2*n+1]=0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",ch+1);
ans=200209230020020923;
n=strlen(ch+1);
pre_work();
for(int i=1;i<=2*n;i++)
{
blft[i]=blft[i-1];
slft[i]=slft[i-1];
rlft[i]=rlft[i-1];
if(ch[i]=='B')blft[i]++;
else
{
rlft[i]++;
slft[i]+=blft[i];
}
}
for(int i=2*n;i;i--)
{
brht[i]=brht[i+1];
srht[i]=srht[i+1];
if(ch[i]=='B')brht[i]++;
else srht[i]+=brht[i];
}
for(int i=1;i<=n;i++)
ans=min(ans,_doudou(i,i+n-1));
printf("%lld\n",ans);
}
return 0;
}
$\Theta (n)$算法:
#include<bits/stdc++.h>
using namespace std;
int n;
char ch[4000001];
long long slft[4000001],srht[4000001],blft[4000001],brht[4000001],rlft[4000001];
long long ans;
long long judge(int l,int v,int r)
{return slft[v]-slft[l-1]-blft[l-1]*(rlft[v]-rlft[l-1])+srht[v+1]-srht[r+1]-brht[r+1]*(rlft[r]-rlft[v]);}
void pre_work()
{
for(int i=1;i<=n;i++)ch[n+i]=ch[i];
blft[0]=slft[0]=rlft[0]=srht[2*n+1]=brht[2*n+1]=0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",ch+1);
ans=200209230020020923;
n=strlen(ch+1);
pre_work();
for(int i=1;i<=2*n;i++)
{
blft[i]=blft[i-1];
slft[i]=slft[i-1];
rlft[i]=rlft[i-1];
if(ch[i]=='B')blft[i]++;
else
{
rlft[i]++;
slft[i]+=blft[i];
}
}
for(int i=2*n;i;i--)
{
brht[i]=brht[i+1];
srht[i]=srht[i+1];
if(ch[i]=='B')brht[i]++;
else srht[i]+=brht[i];
}
int lft=1;
for(int i=1;i<=n;i++)
{
while(lft!=n+i&&judge(i,lft,i+n-1)>=judge(i,lft+1,i+n-1))lft++;
ans=min(ans,judge(i,lft,i+n-1));
}
printf("%lld\n",ans);
}
return 0;
}
rp++
[CSP-S模拟测试]:寿司(暴力)的更多相关文章
- [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania
[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见&quo ...
- [考试反思]1003csp-s模拟测试58:沉淀
稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...
- [考试反思]0814NOIP模拟测试21
前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...
- [考试反思]0729NOIP模拟测试10
安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...
- csp-s模拟测试98
csp-s模拟测试98 $T1$??不是我吹我轻松手玩20*20.$T2$装鸭好像挺可做?$T3$性质数据挺多提示很明显? $One$ $Hour$ $Later$ 这$T1$什么傻逼题真$jb$难调 ...
- csp-s模拟测试96
csp-s模拟测试96 $T1$一眼慢速乘,$T2$稍证一手最优性尝试用神奇数据结构优化,无果,弃.$T3$暴力+信仰. 100 03:16:38 95 03:16:56 35 03:17:10 23 ...
- csp-s模拟测试94
csp-s模拟测试94 一场简单题,打爆了.$T1$脑抽分解质因数准备分子分母消,想了半天发现$jb$互质直接上天,果断码了高精滚蛋.$T2$无脑手玩大样例,突然灵光一闪想到映射到前$K$大小的区间, ...
- csp-s模拟测试93
csp-s模拟测试93 自闭场. $T1$想到$CDQ$,因为复杂度少看见一个$0$打了半年还用了$sort$直接废掉,$T2$,$T3$直接自闭暴力分都没有.考场太慌了,心态不好. 02:07:34 ...
- csp-s模拟测试92
csp-s模拟测试92 关于$T1$:最短路这一定建边最短路. 关于$T2$:傻逼$Dp$这一定线段树优化$Dp$. 关于$T3$:最小生成树+树P+换跟一定是这样. 深入(?)思考$T1$:我是傻逼 ...
随机推荐
- 系统用户与用户组管|chfn、密码管理、身份切换、sudo
2 系统用户与用户组管理 GID为GroupId,即组ID,用来标识用户组的唯一标识符 UID为UserId,即用户ID,用来标识每个用户的唯一标示符 /etc/passwd /etc/shadow ...
- CentOS下搭建docker+.net core
运行环境: CentOS 7.0 容器:Docker 1.13.1 .Net Core版本: .NET Core 2.1,安装详见 CentOS 7 下安装.NET Core SDK 2.1 1.安装 ...
- 小明种苹果(续)第十七次CCF认证
小明种苹果(续)第十七次CCF认证 题目 原题链接 ](http://118.190.20.162/view.page?gpid=T93) 很高心,在现在CCF CSP可以下载自己当时的答卷了,也就是 ...
- c++ const 用法
1. 修饰一般变量,const int a = 10; 表示此变量不能被修改,简单易懂,不多说 2. 修饰指针,主要是下面三种 const int *cp1 = &a; // ...
- 有序无序Ul->Li Ol->Li菜单,默认点击当前弹出下拉,再次点击收起下拉菜单(变形2 ---修饰)
从上面可以看出,两个问题,第一:下拉出现的太快太突然,第二:再点击下一个下拉菜单的时候,上一个不会闭合,针对这两个问题,接下来会一 一解决. 解决下拉太快: js中有个jquery效果,有一个效果是j ...
- PHP MVC结构系统架构设计
今天研究了下PHP MVC结构,所以决定自己写个简单的MVC,以待以后有空再丰富.至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据 ...
- CodeForces - 714E + POJ - 3666 (dp严格单调递增与非严格单调递增)
左偏树 炒鸡棒的论文<左偏树的特点及其应用> 虽然题目要求比论文多了一个条件,但是……只需要求非递减就可以AC……数据好弱…… 虽然还没想明白为什么,但是应该觉得应该是这样——求非递减用大 ...
- Houdini:也许是你未曾听过的最振奋人心的 CSS 进化
原文链接:Houdini: Maybe The Most Exciting Development In CSS You’ve Never Heard Of更多译文将陆续推出,欢迎点赞+收藏+关注我的 ...
- Cockpit- Linux 服务器管理接口
Cockpit- Linux 服务器管理接口 功能 它包含 systemd 服务管理器. 有一个用于故障排除和日志分析的 Journal 日志查看器. 包括 LVM 在内的存储配置比以前任何时候都要简 ...
- Python核心技术与实战——七|自定义函数
我们前面用的代码都是比较简单的脚本,而实际工作中是没有人把整个一个功能从头写到尾按顺序堆到一块的.一个规范的值得借鉴的Python程序,除非代码量很少(10行20行左右)应该由多个函数组成,这样的代码 ...