【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 ...
随机推荐
- Linux常用命令分类
目录:相对路径和绝对路径. 绝对路径:路径的写法[一定由根目录 / 写起],例如: /usr/share/doc 这个目录. 相对路径:路径的写法[不是由 / 写起],例如由 /usr/share/d ...
- bzoj 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛【树形dp】
设f[u][0/1]为u这个点不选/选,转移的时候从儿子转移,f[u][1]=sum(f[son][0])+1,f[u][0]=sum(max(f[son][0],f[e[i].to][1])) #i ...
- event.target 属性返回哪个 DOM 元素触发了事件。
<ul> <li>list <strong>item 1</strong></li> <li><span>list ...
- spring Cache /Redis 缓存 + Spring 的集成示例
spring Cache https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/ spring+redis 缓存 ht ...
- [SDOI2013]泉
题目描述 作为光荣的济南泉历史研究小组中的一员,铭铭收集了历史上x个不同年份时不同泉区的水流指数,这个指数是一个小于. 2^30的非负整数.第i个年份时六个泉区的泉水流量指数分别为 A(i,l),A( ...
- [GDOI2014]拯救莫莉斯
题目描述 莫莉斯·乔是圣域里一个叱咤风云的人物,他凭借着自身超强的经济头脑,牢牢控制了圣域的石油市场. 圣域的地图可以看成是一个n*m的矩阵.每个整数坐标点(x , y)表示一座城市吗,两座城市间相邻 ...
- 浅谈算法——splay
BST(二叉查找树)是个有意思的东西,种类巨TM多,然后我们今天不讲其他的,我们今天就讲splay 首先,如果你不知道Splay是啥,你也得知道BST是啥 如上图就是一棵优美的BST,它对于每个点保证 ...
- ACM_01背包2
背包4 Time Limit: 2000/1000ms (Java/Others) Problem Description: 有n个重量和价值分别为Wi,Vi的物品,现从这些物品中挑选出总量不超过W的 ...
- Kali Linux的介绍
Kali Linux是什么? Kali Linux是一个渗透测试平台兼安全审计平台,它集成了多款漏洞检测.目标识别和漏洞利用工具. Kali Linux是专门用于渗透测试的Linux操作系统:基于De ...
- LN : leetcode 538 Convert BST to Greater Tree
lc 538 Convert BST to Greater Tree 538 Convert BST to Greater Tree Given a Binary Search Tree (BST), ...