题目链接:http://codeforces.com/problemset/problem/486/C

题目意思:给出一个含有 n 个小写字母的字符串 s 和指针初始化的位置(指向s的某个字符)。可以对s进行四种操作:up,down,left,right。up/down是令到对称位置的字符相同所进行的操作次数。假设s[i] != s[j](i, j是对称的,假设分别是a, k),up: a(位置1) 根据字母表顺序变成 k(位置11) 需要 10 次(直接a->k)。down:a 根据 字母表逆向顺序变成 k 需要 16 次(a->z->k)。 left/right 主要是操作移动的指针。假如当前指向pos,left: i: 1~pos-1 中 找到s[i] != s[n-i+1], right: j: pos+1 ~ n 找到 s[j] != s[n-j+1]。

问使得s最终成为回文串需要使用这四种操作的最少次数是多少。

如果按题目要求直接一步一步模拟做,会发现好复杂。做了我两个多小时,无果!不仅指针会随时变动,而且当指向第一个元素的时候,又可以移动到最后一个元素(可以循环),还要比较左右两边的距离再判断移动的方向.......

看了题解,真是太厉害了。其实没有必要考虑这么多,前提是要知道需要变动的位置,这个不难。进行 up/down 操作。然后以 p 为中点向左右两边探测,选择离 p 较近的位置的方向,代表这个方向要走两次,另外那个自然就是一次了。

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std; const int maxn = 1e5 + ;
bool ok[maxn]; string s; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif int n, p;
while (scanf("%d%d", &n, &p) != EOF)
{
cin >> s;
s = "Y" + s; // 下标往右移了一位,刚好对应题目给出的下标
memset(ok, false, sizeof(ok));
int ans = ;
for (int i = ; i <= n/; i++)
{
if (s[i] != s[n-i+]) // 要变动的位置
{
if (abs(p-i) > abs(p-(n-i+))) // p位置离哪边近
ok[n-i+] = true;
else
ok[i] = true;
int tmp = abs(s[i]-s[n-i+]);
ans += min(-tmp, tmp); // 求down/up 操作次数
}
}
// 找出指针移动的最大距离
int l = p, r = p;
for (int i = ; i <= p; i++)
{
if (ok[i])
{
l = i;
break;
}
}
for (int i = n; i >= p; i--)
{
if (ok[i])
{
r = i;
break;
}
}
// 求left/right 操作次数
ans += abs(p-l) + abs(p-r);
ans += min(abs(p-l), abs(p-r)); // 距离短的那边要走两次: lrr, rll(以p为界)
printf("%d\n", ans);
}
return ;
}

以下这个是我的,写得比较痛苦,没有做出来,纪念下(读者请忽略)

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 1e5 + ;
char s[maxn];
int n, p, ans; inline int change_num(int cur)
{
int x = s[cur] - 'a';
int y = s[n-cur-] - 'a';
int change1 = y - x;
int change2 = x + - y;
s[cur] = s[n-cur-];
return min(change1, change2);
} inline int get_moves(int cur) // 这里存在大问题,比较难修改
{
printf("cur = %d\n", cur);
int l = cur - , r = cur + ;
l = (l < ? n - : l);
r = (r >= n ? : r);
int cntl = ;
int cntr = ;
printf("before: l = %d, cntl = %d\n", l, cntl);
printf(" r = %d, cntr = %d\n", r, cntr); while (s[l] == s[n-l-] && l != cur && l != n-l-)
{
cntl++;
l = (l < ? n - : l-);
} while (s[r] == s[n-r-] && r != cur && r != n-r-)
{
cntr++;
r = (r >= n ? : r);
printf("in: r = %d\n", r);
} printf("after: l = %d, cntl = %d\n", l, cntl);
printf(" r = %d, cntr = %d\n", r, cntr);
if (cntl < cntr)
return -cntl;
return cntr;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif while (scanf("%d%d", &n, &p) != EOF)
{
scanf("%s", s);
int cnt = ;
for (int i = ; i < n/; i++)
{
if (s[i] != s[n-i-])
cnt++;
}
int ans = ;
p--;
if (s[p] != s[n-p-])
{
ans += change_num(p);
cnt--;
}
// printf("cnt = %d\n", cnt);
// printf("before: ans = %d\n", ans);
int after, now = p;
while (cnt)
{
int after = get_moves(now);
printf("after = %d\n", after);
now += after;
ans += abs(after);
ans += change_num(now);
printf("s = %s\n", s);
printf("ans = %d\n\n", ans);
cnt--;
if (now == p)
break;
}
printf("%d\n", ans);
}
return ;
}

codeforces 486C. Palindrome Transformation 解题报告的更多相关文章

  1. Codeforces 486C Palindrome Transformation(贪心)

    题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N.指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:事实上仅仅要 ...

  2. codeforces 486C Palindrome Transformation 贪心求构造回文

    点击打开链接 C. Palindrome Transformation time limit per test 1 second memory limit per test 256 megabytes ...

  3. CodeForces 486C Palindrome Transformation 贪心+抽象问题本质

    题目:戳我 题意:给定长度为n的字符串,给定初始光标位置p,支持4种操作,left,right移动光标指向,up,down,改变当前光标指向的字符,输出最少的操作使得字符串为回文. 分析:只关注字符串 ...

  4. Codeforces Round 665 赛后解题报告(暂A-D)

    Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...

  5. Codeforces Round 662 赛后解题报告(A-E2)

    Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...

  6. Codeforces Round 486C - Palindrome Transformation 贪心

    C. Palindrome Transformation time limit per test 1 second memory limit per test 256 megabytes input ...

  7. Codeforces Round #277.5 解题报告

    又熬夜刷了cf,今天比正常多一题.比赛还没完但我知道F过不了了,一个半小时贡献给F还是没过--应该也没人Hack.写写解题报告吧= =. 解题报告例如以下: A题:选择排序直接搞,由于不要求最优交换次 ...

  8. codeforces B. Simple Molecules 解题报告

    题目链接:http://codeforces.com/problemset/problem/344/B 题目意思:这句话是解题的关键: The number of bonds of an atom i ...

  9. 【LeetCode】266. Palindrome Permutation 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcode ...

随机推荐

  1. php版本的discuzX3.2部署的问题收集

    1.登陆后台老是自动退出是怎么回事? 解决方法:用ftp上線下載文件下在跟目錄/config/config_global.php把$_config['admincp']['checkip']  = 1 ...

  2. 系​统​吞​吐​量​(​T​P​S​)​、​用​户​并​发​量​、​性​能​测​试、IO负载学习

    目录 . 如何评价一个系统的性能 . 系统吞度量 . 网络上下行数据量 . 客户端-服务端TCP同时长连接数量 . 系统性能的指标计算 . 系统IO负载 1. 如何评价一个系统的性能 在文章的开始,我 ...

  3. HD2157How many wasy??(十大矩阵问题之八 + 邻接矩阵的应用)

    How many ways?? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. 项目总结—jQuery EasyUI-DataGrid动态加载表头

    http://blog.csdn.net/zwk626542417/article/details/19248747 概要 在前面两篇文章中,我们已经介绍了在jQuery EasyUI-DataGri ...

  5. API与软件架构

    http://blog.csdn.net/horkychen/article/details/46612899 从架构设计的角度来看(所谓的组成论),软件系统就是模块和接口. 模块(层次/组件)决定分 ...

  6. 使用NPOI操作Excel(03、07)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using NPOI.SS. ...

  7. MACD、BOLL、KDJ 三大组合精准把握趋势与买卖!

    先看示意图,下图是布林线的3个轨道,其他都是股价走势 图1 股价,在布林线上轨.下轨之间运作.准确说,这话是不符合逻辑的,不是先有的轨道,然后股价再按照轨道运动.因为轨道是跟股价同时变化的.但是,股价 ...

  8. 周期串(Periodic Strings,UVa455)

    解题思路: 对一个字符串求其最小周期长度,那么,最小周期长度必定是字符串长度的约数,即最小周期长度必定能被字符串长度整除 其次,对于最小周期字符串,每位都能对应其后周期字串的每一位, 即 ABC  A ...

  9. bootshrap会改变IE浏览器滚动条样式

    在某个小网站的开发中 客户一直抱怨在IE11中网页右边滚动条不一样 后来发现在IE11中,有2个页面滚动条会自动隐藏,一开始以为是浏览器默认行为,改了overflow:scroll后也没有用.仔细观察 ...

  10. 微信5.4你所不知道的事 X5浏览引擎提速50%-80%

    微信5.4新增包括搜索公众号.识别图中二维码.面对面收钱等功能,但是你可知道新版微信X5浏览引擎提速了,提升50%-80%的网络传输速度及相同比例流量节省? 从X5浏览引擎开发人员得知,X5浏览技术基 ...