【链接】 我是链接,点我呀:)

【题意】

光标一开始在p的位置
你可以用上下左右四个键位移动光标(左右)或者更改光标所在的字符(上下增加或减少ascill码)
问你最少要操作多少次才能使得字符串变成回文

【题解】

首先把字符串分成两个部分
1..n/2 和 n/2+1..n这两个部分 (如果n是奇数比较特殊,右半部分是n/2+2..n)
然后如果p落在右半部分那个区间的话
就让它做一下对称
到左半部分来
因为不可能从右边那个区间移动到左边那个区间的(跨越n到达1),那样做太不划算
这两个区间其实是等价的,因为转换的代价都是相同的
只需让光标在一个区间里面移动就好
然后我们就只要考虑一个区间了(1..n/2),
先算出来每个位置转换成回文串对应的位置的字符需要的代价cost[i]
然后求一个前缀和(我直接在cost[i]上求的前缀和,直接导致我忘记cost[i]代表的是cost[1..i]。。。。)
然后再把这一个区间分成(1..p-1)和(p+1,n/2)
我们用前缀和求出cost[1..p-1]和cost[p+1,n/2]
这一部分答案是肯定要累加的。
然后我们只要知道我们往左和往右走最近需要走到哪里(因为不一定非得走到1或者走到n/2)
记往左走最少需要走的步数为leftstep,同理向右为rightstep
(如果不用往左走或不用往右走那么对于的xxxstep=0)
那边要的步数少,我们就先走到那边
因为这样的话,回到p位置所需要的花费比较少
则答案累加min(leftstep,rightstep)*2+max(leftstep,rightstep)
这样就做完了!

【代码】

import java.io.*;
import java.util.*; public class Main { static InputReader in;
static PrintWriter out; public static void main(String[] args) throws IOException{
//InputStream ins = new FileInputStream("E:\\rush.txt");
InputStream ins = System.in;
in = new InputReader(ins);
out = new PrintWriter(System.out);
//code start from here
new Task().solve(in, out);
out.close();
} static int N = 50000;
static class Task{ final int N = (int)1e5;
String s;
int n,p;
int cost[]; int get_sum(int l,int r) {
if (l>r) return 0;
return cost[r]-cost[l-1];
} public void solve(InputReader in,PrintWriter out) {
cost = new int[N+10];
n = in.nextInt();p = in.nextInt();
s = in.next();
StringBuilder sb = new StringBuilder(s);
sb.insert(0, ' ');
s = sb.toString();
int half = n/2;
for (int i = 1;i <= half;i++) {
int j = n-i+1;
int x = s.charAt(i)-'a'+1;
int y = s.charAt(j)-'a'+1;
int temp1 = Math.abs(x-y);
int temp2 = 26-Math.max(x, y) + Math.min(x, y) - 1 + 1;
cost[i] = Math.min(temp1, temp2);
}
for (int i = 1;i <= half;i++) cost[i]+=cost[i-1]; if (cost[half]==0) {
out.println(0);
return;
}
int ans = 0;
if (n%2==1 && p==half+1) {
ans++;
p--;
}
if (p>half) {
int delta;
if (n%2==1) {
delta = p-(half+1);
p = half+1-delta;
}else {
delta = p-half;
p = half-delta+1;
}
}
ans = ans + get_sum(p,p);
int leftcost = get_sum(1,p-1);
int rightcost = get_sum(p+1,half);
ans = ans + leftcost + rightcost;
int leftstep = 0,rightstep = 0;
int temp = 0;
for (int i = p-1;i >= 1;i--) {
if (temp==leftcost) break;
leftstep++;
temp+=get_sum(i,i);
}
temp = 0;
for (int i = p+1;i <= half;i++) {
if (temp==rightcost) break;
rightstep++;
temp+=get_sum(i,i);
}
//out.println("leftstep="+leftstep+" rightstep="+rightstep);
//out.println("leftcost="+leftcost+" rightcost="+rightcost);
//out.println("ans="+ans);
int mi = Math.min(leftstep, rightstep);
int ma = Math.max(leftstep, rightstep);
ans = ans + mi*2 + ma;
out.println(ans);
}
} static class InputReader{
public BufferedReader br;
public StringTokenizer tokenizer; public InputReader(InputStream ins) {
br = new BufferedReader(new InputStreamReader(ins));
tokenizer = null;
} public String next(){
while (tokenizer==null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(br.readLine());
}catch(IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
} public int nextInt() {
return Integer.parseInt(next());
}
}
}

【Codeforces 486C】Palindrome Transformation的更多相关文章

  1. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  2. 【POJ 1159】Palindrome

    [POJ 1159]Palindrome 近期各种题各种奇葩思路已经司空见惯了...又新出个滚动数组= = 该题另一点须要知道 最少须要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 ...

  3. 【codeforces 798A】Mike and palindrome

    [题目链接]:http://codeforces.com/contest/798/problem/A [题意] 让你严格改变一个字符,使得改变后的字符串为一个回文串; 让你输出可不可能; [题解] 直 ...

  4. 【19.77%】【codeforces 570D】Tree Requests

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. 【34.88%】【codeforces 569C】Primes or Palindromes?

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. 【25.64%】【codeforces 570E】Pig and Palindromes

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. 【44.19%】【codeforces 608D】Zuma

    time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...

  8. 【Leet Code】Palindrome Number

    Palindrome Number Total Accepted: 19369 Total Submissions: 66673My Submissions Determine whether an ...

  9. 【codeforces 707E】Garlands

    [题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...

随机推荐

  1. bzoj 1594: [Usaco2008 Jan]猜数游戏【二分+线段树】

    写错一个符号多调一小时系列-- 二分答案,然后判断这个二分区间是否合法: 先按值从大到小排序,然后对于值相同的一些区间,如果没有交集则不合法:否则把并集在线段树上打上标记,然后值小于这个值的区间们,如 ...

  2. P2973 [USACO10HOL]赶小猪

    跟那个某省省选题(具体忘了)游走差不多... 把边搞到点上然后按套路Gauss即可 貌似有人说卡精度,$eps≤1e-13$,然而我$1e-12$也可以过... 代码: #include<cst ...

  3. Linux学习笔记之Linux系统启动过程

    Linux系统的启动过程可以分为五个阶段: 内核的引导 运行init 系统初始化 建立终端 用户登录系统 1.内核引导: 当计算机打开电源后,首先进行BIOS开机自检,按照BIOS中设置的启动设备(一 ...

  4. Android 性能优化(11)网络优化( 7)Optimizing for Doze and App Standby

    Optimizing for Doze and App Standby In this document Understanding Doze Doze restrictions Adapting y ...

  5. Spring 侵入式和非侵入式

    1.非侵入式的技术体现 允许在应用系统中自由选择和组装Spring框架的各个功能模块,并且不强制要求应用系统的类必须从Spring框架的系统API的某个类来继承或者实现某个接口. 2.如何实现非侵入式 ...

  6. 基于Web的Kafka管理器工具之Kafka-manager的编译部署详细安装 (支持kafka0.8、0.9和0.10以后版本)(图文详解)(默认端口或任意自定义端口)

    不多说,直接上干货! 至于为什么,要写这篇博客以及安装Kafka-manager? 问题详情 无奈于,在kafka里没有一个较好自带的web ui.启动后无法观看,并且不友好.所以,需安装一个第三方的 ...

  7. express模块安装使用命令配置

    之前的博客nodejs安装和配置好路径之后就可以安装express了: 随便打开个文件夹右键选择,git bash here 命令行里输入[npm install express -g] -g是全局安 ...

  8. Codewars练习Python

    计算一个数组的中间数,数的两边和相等,并返回index值 如:数组[1,2,3,4,6] 返回3(数组序号从0开始) def find_even_index(arr): ""&qu ...

  9. React组件的防呆机制(propTypes)

    Prop验证 随着应用不断变大,为了保证组件被正确使用变得越来越重要.为此我们引入propsTypes.React.PropTypes提供很多验证器(valodator)来验证传入的数据的有效性.当向 ...

  10. 简单了解了下SEO与SEM的机制

    SEO:搜索引擎优化SEM:搜索引擎营销 SEO排名机制:搜索引擎蜘蛛 权重 算法 排名规则 搜索引擎提交入口: 1.百度搜索网站登入口 2.Google网站登入口 3.360搜索引擎登入入口 4.搜 ...