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 ...
随机推荐
- 【转】从Go、Swift语言出发
Google于2009年第一次提出了Go的构思,Facebook在去年春天引入了Hack,随后不久Apple也发布了其Swift语言. 在战争中,胜利者写历史书:在科技中,赢的公司都在写编程语言.互联 ...
- 38.Android之ListView简单学习(一)
android中ListView用的很普遍,今天来学习下,本篇主要以本地数据加载到listview,后面会学习从网络获取数据添加到listview. 首先改下布局文件: <?xml versio ...
- 37.Activity之间的转换以及数据的传递(Intent)学习
Intent简介: 在一个Androi ...
- this的使用
1.使用this调用本类中的属性 class Person{ private String name; private int age; public Person(String name,int a ...
- sql server规范
常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自增长标识建议采用bigint ...
- POJ1845Sumdiv(求所有因子和 + 唯一分解定理)
Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 17387 Accepted: 4374 Descripti ...
- TEXT宏,TCHAR类型
TCHAR *ptch = TEXT("This is a const string."); 如果使用UNICODE字符集, 则TEXT("This is a const ...
- spring bean id和bean name的区别
今天在分析问题时发现一个大家平时都不太注意的spring 配置问题,发出来分享下: 首先澄清一个概念: 同名bean:多个bean 有相同的 name 或者 id,称之为同名bean <bean ...
- ExecutorService的十个使用技巧
ExecutorService] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent /ExecutorService.ht ...
- 新浪微博客户端(3)-封装UIBarButtonItem
单独给NavigationBar上的两个NavigationItem设置图片显得比较麻烦,下面对创建单个UIBarButtonItem的过程进行封装. UIBarButtonItem+Extensio ...