ssoj2435 回文串游戏(贪心)
2015-10-06 20:01
274 查看
题意:给一个串,和一个初始位置,每次操作可以左移一位或右移一位,当前值加一或减一,要求最少操作次数使串变成回文串。
思路:只要处理初始位置所在的半边。
注意:一开始写的程序,不必更改的和只有一位要更改的,情况一样,要处理一下。
思路:只要处理初始位置所在的半边。
注意:一开始写的程序,不必更改的和只有一位要更改的,情况一样,要处理一下。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int maxn=100055; int f[maxn],n,p,mid,ans=0; char s[maxn]; inline int get(){ char c;while(!isdigit(c=getchar())); int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48; return v; } int main(){ n=get();p=get(); memset(f,0,sizeof(f)); scanf("%s",s+1); mid=n/2; for(int i=1;i<=mid;++i)f[i]=f[n-i+1]=min(abs(26-abs(s[i]-s[n-i+1])),abs(s[i]-s[n-i+1])); if(p<=mid){ int l=1,r=mid; while(l<mid && f[l]==0)++l; while(r>l && f[r]==0)--r; if(l==r && f[l]==0){printf("0\n");return 0;} for(int i=l;i<=r;++i)ans+=f[i]; int len=min(abs(p-l),abs(r-p)); ans+=len+r-l; } else{ int l=mid+1,r=n; while(l<n && f[l]==0)++l; while(r>l && f[r]==0)--r; if(l==r && f[l]==0){printf("0\n");return 0;} for(int i=l;i<=r;++i)ans+=f[i]; int len=min(abs(p-l),abs(r-p)); ans+=len+r-l; } printf("%d\n",ans); return 0; }
相关文章推荐
- 【牛刀小试2】password保
- 写出最小公因数
- 最小生成树kruskal算法(并查集)
- onethink后台一直提示验证码不正确,或提示用户名不存在或被禁用
- 深度学习(七)caffe源码c++学习笔记
- mongodb操作之mongoose
- ruby安装顺序简单讲解
- Java第二章动手动脑练习
- 程序员规划(转载)
- ACM学习历程—HDU5476 Explore Track of Point(平面几何)(2015上海网赛09题)
- 网页滚动到底部自动加载
- [MySQL Reference Manual]14 InnoDB存储引擎
- css多个class时的选择器用法
- 9月28日项目范围管理论文提纲
- xml解析 dom4j通过XPath找标签
- hdu 5432 Minimum Cut 树链剖分nlogn
- 条款18:让接口容易被正确使用,不宜被误用。
- POJ 2251 Dungeon Master(bfs)
- 深入浅出MyBatis-Configuration
- UI 动画之反射变换的旋转