codeforces 486C. Palindrome Transformation 解题报告
题目链接: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 解题报告的更多相关文章
- Codeforces 486C Palindrome Transformation(贪心)
题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N.指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:事实上仅仅要 ...
- codeforces 486C Palindrome Transformation 贪心求构造回文
点击打开链接 C. Palindrome Transformation time limit per test 1 second memory limit per test 256 megabytes ...
- CodeForces 486C Palindrome Transformation 贪心+抽象问题本质
题目:戳我 题意:给定长度为n的字符串,给定初始光标位置p,支持4种操作,left,right移动光标指向,up,down,改变当前光标指向的字符,输出最少的操作使得字符串为回文. 分析:只关注字符串 ...
- Codeforces Round 665 赛后解题报告(暂A-D)
Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...
- Codeforces Round 662 赛后解题报告(A-E2)
Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...
- Codeforces Round 486C - Palindrome Transformation 贪心
C. Palindrome Transformation time limit per test 1 second memory limit per test 256 megabytes input ...
- Codeforces Round #277.5 解题报告
又熬夜刷了cf,今天比正常多一题.比赛还没完但我知道F过不了了,一个半小时贡献给F还是没过--应该也没人Hack.写写解题报告吧= =. 解题报告例如以下: A题:选择排序直接搞,由于不要求最优交换次 ...
- codeforces B. Simple Molecules 解题报告
题目链接:http://codeforces.com/problemset/problem/344/B 题目意思:这句话是解题的关键: The number of bonds of an atom i ...
- 【LeetCode】266. Palindrome Permutation 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcode ...
随机推荐
- Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析
这一章,我们来分析Cocos2d-x 事件机制相关的源码, 根据Cocos2d-x的工程目录,我们可以找到所有关于事件的源码都存在放在下图所示的目录中. 从这个event_dispatcher目录中的 ...
- 6.Android之switch和togglebutton按钮学习
Switch和ToggleButton按钮在手机上也经常看到,比如手机设置里面wlan,蓝牙,gps开关等. 首先在工具上拖进一个switch和togglebutton开关按钮,如图 生成xml代码如 ...
- BZOJ-3226 校门外的区间 线段数+拆点(类似的思想)
shabi题....bzoj关键字检查freopen??可怕,,1A的卡了一小时.... 3226: [Sdoi2008]校门外的区间 Time Limit: 10 Sec Memory Limit: ...
- java将一维数组拆分成二维数组
package staticFactory; public class Array { public static void main(String[] args) { String[] a=new ...
- WGS84、Web墨卡托、火星坐标、百度坐标互转
转自:1.http://blog.csdn.net/wildboy2001/article/details/12031351 2.http://kongxz.com/2013/10/wgs-cgj/ ...
- CodeForces 701A Cards
直接看示例输入输出+提示 1. 统计所有数的和 sum,然后求 sum/(n/2) 的到一半数的平均值 6 1 5 7 4 4 3 ->1+5+7+4+4+3=24 分成3组 每组值为8 in ...
- 如何使用网盘托管git项目
话说近年来git已经成为项目源代码管理的标准工具,有不少免费托管网站可供使用,详情参考这篇文章: http://www.cnblogs.com/zdz8207/archive/2012/05/20/2 ...
- MIM协议与Base64编码
MIME Protocol 1. MIME的全称是"Multipurpose Internet Mail Extensions",中译为"多用途互联网邮件扩展" ...
- Silverlight实例教程 – Datagrid,Dataform数据验证和ValidationSummary(转载)
Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...
- System.gc()与Object.finalize()的区别
finalize()是由JVM自动调用的,你可以用System.gc(),但JVM不一定会立刻执行,JVM感觉内存空间有限时,才会开始执行finalize(),至于新的对象创建个数和被收集个数不同是因 ...