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

【题意】

光标一开始在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. Behaviac 腾讯开源行为树 简介(给策划)

    1.为什么使用BT FSM模型的优势之一是简单.但是FSMs需要用转换(Transition)连接状态(State),因此,状态(State)失去了模块性(Modularity). BT的主要优势之一 ...

  2. NestedPreb

    屌丝手动版 One of the things we’re sorely missing from Unity is nested prefabs. So we rolled this little ...

  3. 略微讲讲最近的 webpack 该如何加快编译

    首先假设 基础的环境是有 creat-react-app 所创建的 即所有基础的loader,插件的 cache 都已经缓存了 在这种情况下想加速,真是很难 不过,有一个插件是可以观察 各个模块所花的 ...

  4. Chrome教程之NetWork面板分析网络请求

    官方文档:https://developers.google.com/web/tools/chrome-devtools/network/ 最近打算写一写Chrome教程文档,不知道大家最感兴趣的是什 ...

  5. CSMA/CA协议

    802.11中采用CSMA/CA协议来规定多个工作节点共用信道的问题. CSMA/CA的全称是Carrier sense multiple access with collision avoidanc ...

  6. Vue组件之间通信的三种方式

    最近在看梁颠编著的<Vue.js实战>一书,感觉颇有收获,特此记录一些比价实用的技巧. 组件是MVVM框架的核心设计思想,将各功能点组件化更利于我们在项目中复用,这类似于我们服务端面向对象 ...

  7. C#和Java在语法上的差异(原创,持续更新中)

    1.switch  C#一直支持String类型 Java直到1.7才支持 2.C#里String有Length属性 Java里是Length方法 3.C#中修饰class的sealed效果与Java ...

  8. offset家族基本简介

    Offset家族简介 offset这个单词本身是--偏移,补偿,位移的意思. js中有一套方便的获取元素尺寸的办法就是offset家族: offsetWidth和offsetHight 以及offse ...

  9. EF CodeFirst 不得不说的Where与OrderBy

    先来聊上5毛钱的“排序” Code: using (ApplicationDbContext Db=new ApplicationDbContext()) { var res = Db.Threes. ...

  10. [Windows Server 2003] 初识Windows Server 2003

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:初次见识W ...