题意简述

给定一个由A C G T四个字母组成的密码锁(每拨动一次 A变C C变G G变T T变A)

密码锁有n位 规定每次操作可以选取连续的一段拨动1~3次

问最少几次操作可以将初始状态变到末状态

并且把每次操作输出

(此题有spj)

---------------------------------------------------------------------------------------------------------

为了方便叙述 所有没有明确说明的位置均是在$mod4$意义下的

首先我们显然可以明白一个性质 操作顺序是没关系的

有关系的只是每个位置被拨动的次数

比赛的时候一开始想的是比较随意的贪心 然而是有反例的

最后剩下30min的时候 从数据范围想到了区间Dp

然而这题并不是一般的区间Dp

最小操作数好求然而操作方案难以记录

补题的时候 最终又去想象有没有什么更好的贪心思路

---------------------------------------------------------------------------------------------------------

我们用一个高度数组h记录从初始状态到末状态每个位置需要拨动的次数

比如样例

AGGTCAT

AAACTAA

高度数组h便是 0222201

我们再定义一个delta数组 代表所有的$h[i]-h[i-1]$

那么从$1$到$n+1$delta数组的值便是 02000213

(这样的构造类似与用树状数组维护区间加减值的做法 不过这种思想的具体名称我也不知道)

显然我们每次最优可以将两个2变为0 或者将一个1和一个3变为0

于是这样就可以做了?

然而只是这样做的话会RE11

---------------------------------------------------------------------------------------------------------

比如这样一个样例

AA

GT

高度数组h为 23

delta数组为 211

于是并不能找出两个2或者一个1一个3来配对消除

既然无法一次消两个 我们就一次消一个吧

不过显然是不能使一些已经消除的部分又出现

所以直接找两个非0的进行处理 把其中一个变为0就好了

(注意到delta数组之和为0 所以最后一定不会只剩下一个非0的)

#include <bits/stdc++.h>
using namespace std;
const int N=;
char s1[N],s2[N];
int h[N],delta[N],cnt[];
int L[N],R[N],d[N];
int n,ans;
int main()
{
#ifdef ONLINE_JUDGE
freopen("transform.in","r",stdin);
freopen("transform.out","w",stdout);
#endif
scanf("%s%s",&s1[],&s2[]);
n=strlen(&s1[]);
for(int i=;i<=n;++i)
{
if(s1[i]=='A')
h[i]=-;
else if(s1[i]=='C')
h[i]=-;
else if(s1[i]=='G')
h[i]=-;
else
h[i]=-;
if(s2[i]=='A')
h[i]+=;
else if(s2[i]=='C')
h[i]+=;
else if(s2[i]=='G')
h[i]+=;
else
h[i]+=;
h[i]=h[i]<?h[i]+:h[i];
}
for(int i=;i<=n+;++i)
{
delta[i]=(h[i]-h[i-]+)%;
cnt[delta[i]]++;
}
while(cnt[]!=n+)
{
++ans;
int i=;
while(!delta[i])
++i;
int j=i+;
while(delta[j]+delta[i]!=&&j<=n+)
++j;
if(j<=n+)
{
L[ans]=i;
R[ans]=j-;
d[ans]=delta[i];
cnt[delta[i]]--;
cnt[delta[j]]--;
cnt[]+=;
delta[i]=delta[j]=;
}
else
{
j=i+;
while(!delta[j])
++j;
L[ans]=i;
R[ans]=j-;
d[ans]=delta[i];
cnt[delta[i]]--;
cnt[delta[j]]--;
cnt[]++;
cnt[(delta[j]+delta[i])%]++;
delta[j]=(delta[j]+delta[i])%;
delta[i]=;
}
}
printf("%d\n",ans);
for(int i=;i<=ans;++i)
printf("%d %d %d\n",L[i],R[i],d[i]);
return ;
}

codeforces gym 100345I Segment Transformations [想法题]的更多相关文章

  1. Codeforces Gym 100431D Bubble Sort 水题乱搞

    原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-an ...

  2. Codeforces Gym 100803D Space Golf 物理题

    Space Golf 题目连接: http://codeforces.com/gym/100803/attachments Description You surely have never hear ...

  3. Codeforces gym 100685 C. Cinderella 水题

    C. CinderellaTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/C ...

  4. Codeforces GYM 100114 B. Island 水题

    B. Island Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Description O ...

  5. codeforces 657C - Bear and Contribution [想法题]

    题目链接: http://codeforces.com/problemset/problem/657/C ----------------------------------------------- ...

  6. Codeforces Gym 100286G Giant Screen 水题

    Problem G.Giant ScreenTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/con ...

  7. CodeForces - 156B Suspects 逻辑 线性 想法 题

    题意:有1~N,n(1e5)个嫌疑人,有m个人说真话,每个人的陈述都形如X是凶手,或X不是凶手.现在给出n,m及n个陈述(以+x/-X表示)要求输出每个人说的话是true ,false or notd ...

  8. CodeForces - 798D Mike and distribution 想法题,数学证明

    题意:给你两个数列a,b,你要输出k个下标,使得这些下标对应的a的和大于整个a数列的和的1/2.同时这些下标对应的b //题解:首先将条件换一种说法,就是要取floor(n/2)+1个数使得这些数大于 ...

  9. CodeForces - 55C Pie or die 想法题(猜程序)

    http://codeforces.com/problemset/problem/55/C 题意:一个博弈. 题解:瞎猜,目前不清楚原理 #include<iostream> #inclu ...

随机推荐

  1. opencv部署服务器报错

    报错内容: ImportError: libSM.so.6: cannot open shared object file: No such file or directory 解决办法: sudo ...

  2. MyEclipse停止自带插件的启动

    MyEclipse启动时因为自身带有很多的插件,所以在启动时运行的速度特别慢,所以可以选择一下启动时的插件,将不使用的插件选择在MyEclipse启动时不起动. 步骤如下: windows->p ...

  3. seaborn教程2——颜色调控

    原文转载 https://segmentfault.com/a/1190000014966210 Seaborn学习大纲 seaborn的学习内容主要包含以下几个部分: 风格管理 绘图风格设置 颜色风 ...

  4. 20、numpy——IO

    NumPy IO Numpy 可以读写磁盘上的文本数据或二进制数据. NumPy 为 ndarray 对象引入了一个简单的文件格式:npy. npy 文件用于存储重建 ndarray 所需的数据.图形 ...

  5. jxl读取excel浮点数据时,小数点后三位截取问题

    今天导入Excel数据时,发现很多浮点数据被自动四舍五入只保留了三位,原来是jxl里对getContents()进行了封装,对数值型数据作了该处理.一般我们会对读取excel的一整套流程作为工具类,那 ...

  6. xcode 5.0 连接svn error -(NSURLErrorDomain error -1012)

    xcode 5.0连接 svn server, check out时出现如下error : The operation couldn’t be completed. (NSURLErrorDomain ...

  7. 二、TortoiseSVN 合并、打分支、合并分支、切换分支

    一.合并 点击Edit conflict来编辑冲突: 在合并后的枝干对应栏中编辑后,Save保存后关闭. 二.TortoiseSVN 打分支.合并分支.切换分支 1.SVN打分支 方式一:先检出,再打 ...

  8. [前端自动化]grunt的简单使用

    前言 现在前端自动化已经是家常便饭,各种工具也是层出不穷,grunt.gulp.webpack是应用最广的三种工具,虽然grunt看似已垂垂老矣,但是以前写的很多项目一直用的就是grunt,温故方能知 ...

  9. RequestMappingHandlerMapping详解

    我们先理简单梳理一个关系 关系梳理 spring ioc 是spring的核心,用来管理spring bean的生命周期 MVC 是一种使用 MVC(Model View Controller 模型- ...

  10. Flutter日曆國際化

    Flutter自带的日期选择器是showDatePicker,时间选择器是showTimePicker. 这两个选择器默认的显示效果都是英文的,我们是在中国,那么就需要将其显示成中文版的,这就涉及到F ...