ssoj2435 回文串游戏(贪心)

来源:互联网 发布:常用的网络通信协议 编辑:程序博客网 时间:2024/05/20 03:46

题意:给一个串,和一个初始位置,每次操作可以左移一位或右移一位,当前值加一或减一,要求最少操作次数使串变成回文串。

思路:只要处理初始位置所在的半边。

注意:一开始写的程序,不必更改的和只有一位要更改的,情况一样,要处理一下。


#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;}


0 0
原创粉丝点击