【Codeforces 486C】Palindrome Transformation
【链接】 我是链接,点我呀:)
【题意】
光标一开始在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的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【POJ 1159】Palindrome
[POJ 1159]Palindrome 近期各种题各种奇葩思路已经司空见惯了...又新出个滚动数组= = 该题另一点须要知道 最少须要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 ...
- 【codeforces 798A】Mike and palindrome
[题目链接]:http://codeforces.com/contest/798/problem/A [题意] 让你严格改变一个字符,使得改变后的字符串为一个回文串; 让你输出可不可能; [题解] 直 ...
- 【19.77%】【codeforces 570D】Tree Requests
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【34.88%】【codeforces 569C】Primes or Palindromes?
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【25.64%】【codeforces 570E】Pig and Palindromes
time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【44.19%】【codeforces 608D】Zuma
time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...
- 【Leet Code】Palindrome Number
Palindrome Number Total Accepted: 19369 Total Submissions: 66673My Submissions Determine whether an ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
随机推荐
- struct框架
配置文件struct-config.xml<?xml version="1.0"encoding="UTF-8"?><!DOCTYPE str ...
- P3343 [ZJOI2015]地震后的幻想乡
传送门 给积分大佬跪了 再给状压大佬也跪了 //minamoto #include<bits/stdc++.h> #define rint register int #define ll ...
- springboot(三)配置日志
github代码:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-serviceSLF ...
- 最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱
题目传送门 /* KM:裸题第一道,好像就是hungary的升级版,不好理解,写点注释 KM算法用来解决最大权匹配问题: 在一个二分图内,左顶点为X,右顶点为Y,现对于每组左右连接Xi,Yj有权w(i ...
- 解决:org.springframework.tuple.spel.TuplePropertyAccessor
原来运行调试正常的项目,今天启动时报“java.lang.IllegalStateException: ApplicationEventMulticaster not initialized”错误.从 ...
- 使用wkwebview后,页面返回不刷新的问题
onpageshow 事件在用户浏览网页时触发. onpageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,即 ...
- 浅谈css的行内类型标签和块级标签
常用标签的行内类型标签有:a.span.img:块级标签有:div.p.h1~6.ul.ol.li.dl.dt.dd. 行内类型标签的特征:标签的大小由标签的内容决定,不能设置width和height ...
- python自动化--语言基础二运算符、格式化输出、条件语句、循环语句、列表、元组
运算符包括:算术运算符.比较运算符.赋值运算符.逻辑运算符.成员运算符.身份运算符. 算术运算符 % 取模(余数) // 取相除的整数部分 / (5/2=2.5) 比较运算符 == 等于 ...
- Linux 学习(三)
Linux进程 1.进程 进程:可执行应用程序执行后产生的对应的进程,重量级:进程是由一个线程或多个线程构成: 线程:是计算机中的最小单位,轻量级(依赖和物理性是独立存在的).损耗较低 假设进程1是由 ...
- vs2017 visual studio2017 密钥 激活码
企业版Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF 专业版Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH