Codeforces 486C Palindrome Transformation 贪心

点击打开链接

题意:给出string长度n<=1e5(cyclic) 和一个游标p,问最小花费多少次操作能把string变成回文 .(4个操作:左右移动游标p,增大或者减小游标所指的值)

若s[i]!=s[n-i+1] 则要修改其中一个的值,最多修改n/2次,每次花费值时固定的 则只有求出最少的移动距离即可.

贪心: "1  ..p .. n/2....n" 可以看出p~n,和p~n/2~1的移动距离时一样的,则p可以只在1~n/2范围内移动,求出要修改的范围mn~mx确定移动顺序即可

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+20;
char s[N];
int n,p,w[30][30];
int main()
{
	//w[i][j] the minnum cost of changing char i to char j
	for(int i=1;i<=26;i++)
	{
		for(int j=i;j<=26;j++)
		{
			w[i][j]=w[j][i]=min(j-i,i+26-j);
		}
	}
	while(cin>>n>>p)
	{
		scanf("%s",s+1);
		int res=0,mx=0,mn=1e6;
		//在n/2~n做修改等价于在 1~n/2做修改. 
		if(p>n/2)
		{
			p=n-p+1;
		}
		for(int i=1;i<=n/2;i++)
		{
			//修改s[i]的代价 
			if(s[i]!=s[n-i+1])
			{
				res+=w[s[i]-'a'+1][s[n-i+1]-'a'+1];
				mx=max(mx,i);
				mn=min(mn,i);
			}
		}
		if(res==0)
		{
			cout<<0<<endl;
			continue;
		}
		//修改范围为mn~mx
		//p的移动范围最大为1~n/2,根据mn,mx,p确定移动顺序即可 
		if(p<=mn)
		res+=(mx-p);
		else if(p>mn&&p<mx)
		{
			int a=min(p-mn,mx-p);
			int b=max(p-mn,mx-p);
			res+=2*a+b;
		}
		else
		res+=(p-mn);
		
		cout<<res<<endl;		
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值