题目描述
Martin 眼睛出问题了。
对于一个单词,他每次眨眼,在他眼中这个单词的字母便会发生如下的变化(下述「倒数第 k 个」「第 k 个」等都是对于变化前的单词而言的):
- 最后一个字母移动到第 1,2 个字母之间。
- 倒数第二个字母移动到第 2,3 个字母之间。
- … …… …
- 倒数第 k 个字母移动到第 k,k+1 个字母之间。
例如,单词 abcdef 在他眨眼后会变成 afbecd。
如果 Martin 再次眨眼后,相同的事情仍会发生。
给定 Martin 眨眼的次数 X 和他看到的单词 s,求出原本的单词。
输入格式
第一行一个整数 X,表示 Martin 眨眼的次数。
第二行一个字符串 s,表示 Martin 看到的单词。
输出格式
仅一行一个字符串,即原本的单词。
输入输出样例
输入 #1
4 acefdb输出 #1
abcdef
输入 #2
1000 aaaaaa输出 #2
aaaaaa
输入 #3
11 srama输出 #3
sarma
说明/提示
样例 1 说明
变化过程为:abcdef→afbecd→adfcbe→aedbfc→acefdb。
数据规模与约定
- 对于 50%50% 的数据,有1≤X≤100。
- 对于 100%100% 的数据,有 1≤X≤
,33≤∣s∣≤
。
来源
本题译自 COCI2013-2014 CONTEST 2 T3 SLOM。
按照原题数据配置,本题满分 100 分。
题目难度
普及-
参考思路
首先枚举一下操作多次后的字符串:
设原始字符串:123456
。
眨眼 1 次 | 162534 |
---|---|
眨眼 2 次 | 146235 |
眨眼 3 次 | 154263 |
眨眼 4 次 | 135642 |
眨眼 5 次 | 123456 |
如果仔细观察上面的变化,你会发现原始的字符串和第五次眨眼是一样的,所以我们可以判断出字符串变化是循环的。
思路
考虑插入操作,我们可以用 C++ 中的 STL 里的神器:vector
。
它可以随着元素的多少而改变大小,下面简单介绍几个常用操作:
- 定义:
vector<类型>标识符
; - 使用:C++ vector用法。
了解了 vector
我们可以开始着手写代码了。
首先,我们要找到字符串 s 的循环次数,可以通过暴力来解决。
最后,获取了循环次数后,可以减少操作的次数,只要记录循环中每一次操作后的序列,直接输出 nmodk 号的序列就解决了这道题。
参考代码
#include<iostream>
#include<string>
using namespace std;
const int N=1e3+5;
int n,l,p;
string a,ji[2*N];
char t[N];
int main(){
cin>>n>>a;
l=a.length();
for(int i=1;i<=n;i++ )
{
for(int j=0;j<l;j++)
{
if(j%2==0) t[j/2]=a[j];
else t[l-j/2-1]=a[j];
}
for(int j=0;j<l;j++)
{
a[j]=t[j];
}
if(ji[1]==a) break;
ji[++p]=a;
}
if(n%p==0) cout<<ji[p];
else cout<<ji[n%p];
return 0;
}