CodeForces 486C Palindrome Transformation

题意:

n(10^5)个字符  光标停在第pos个字符上  光标可以左右任意移动  而且可以从最左移到最右也可以从最右移到最左  在光标处的字符可以按字母顺序或倒序更改  更改也可以a->z或者z->a  光标移动和字符更改都需要1s  问最短几s能把串变成回文的

思路:

最后的状态是一定的  因此更改的次数和策略无关  扫一遍就可以知道更改最少需要几s

光标移动需要一定的策略  容易想到最优的方法一定是在字符串的一半移动  因此记录在字符串左一半和右一半最远的不回文的位置  让光标移动就好了

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long LL;
#define N 100010

int len, now, ans, res = N;
char s[N];
int wa[N];

int main() {
    scanf("%d%d%s", &len, &now, s);
    now--;
    int L = len, R = -1;
    for (int l = 0, r = len - 1; l < r; l++, r--) {
        if (s[l] != s[r]) {
            int f = abs(s[l] - s[r]);
            ans += min(f, 26 - f);
            wa[l] = wa[r] = 1;
            L = min(L, l);
            R = max(R, l);
        }
    }
    if (ans) {
        res = min(res, min(abs(now - L) + R - L, abs(now - R) + R - L));
        swap(L, R);
        L = len - 1 - L;
        R = len - 1 - R;
        res = min(res, min(abs(now - L) + R - L, abs(now - R) + R - L));
        ans += res;
    }
    printf("%d\n", ans);
    return 0;
}
时间: 2024-10-14 23:20:02

CodeForces 486C Palindrome Transformation的相关文章

Codeforces 486C Palindrome Transformation(贪心)

题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N,指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:其实只要是对称位置不相同的,那么指针肯定要先移动到这里,修改字符只需要考虑两种方向哪种更优即 可.然后将所有需要到达的位置跳出来,贪心处理. #include <cstdio> #include <cstring> #include <cstdlib> #include <vec

贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation

题目传送门 1 /* 2 贪心+构造:因为是对称的,可以全都左一半考虑,过程很简单,但是能想到就很难了 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-3 9:14:02 7 File Name :B.cpp 8 *************************************************/ 9 10 #include

Codeforces 346C Number Transformation II 构造

题目链接:点击打开链接 = = 990+ms卡过 #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<vector> #include<set> using namespace std; #define N 100010 #define L(x) (x<<1) #define R(x) (x<<

Codeforces 159D Palindrome pairs

http://codeforces.com/problemset/problem/159/D 题目大意: 给出一个字符串,求取这个字符串中互相不覆盖的两个回文子串的对数. 思路:num[i]代表左端点在i这个位置的回文串个数,然后用树状数组维护sum[i],代表回文串右端点小于等于i的回文串数,总复杂度:O(n^2) 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstr

Codeforces 932G Palindrome Partition - 回文树 - 动态规划

题目传送门 通往???的传送点 通往神秘地带的传送点 通往未知地带的传送点 题目大意 给定一个串$s$,要求将$s$划分为$t_{1}t_{2}\cdots t_{k}$,其中$2\mid k$,且$t_{i} = t_{k - i}$,问方案数. 直接做不太好做.虽然可以$O(n^{2})$进行动态规划. 考虑做一步转化:设$s' = s_{1}s_{n}s_{2}s_{n - 1}\cdots s_{n / 2}s_{n / 2 + 1}$. 然后它的一个偶回文划分可以和原来的划分一一对应.

Codeforces 251C Number Transformation

Number Transformation 我们能发现这个东西是以2 - k的lcm作为一个循环节, 然后bfs就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int,

CodeForces 346C Number Transformation II

Number Transformation II 题解: 对于操作2来说, a - a % x[i] 就会到左边离a最近的x[i]的倍数. 也就是说 [ k * x[i] + 1,  (k+1)* x[i] -1 ]这段区间的的数都会走到 k * x[i]上. 所以对于每个位置都先计算出他到右边最远的覆盖位置. 然后在反着求出每个位置能往左走走到的最远的位置. 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freo

CodeForces 7D Palindrome Degree

字符串hash.首先说下需要注意的地方:当对Mod取余时,可能造成本不相同的,取余结束之后相同了. 此时应对多个不同的Mod取余,多次计算只能说降低上述情况的发生.感觉正式比赛中不会有这种题,比较拼RP. 比如此题,Mod = 2^32,可以,Mod = 2^64,WA了... #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <

CodeForces 7D Palindrome Degree 字符串hash

题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #include<string> #include<stdlib.h> #include<a