实验任务
小光头找到小菇凉存档后遇到了意外,需要重新开始。可是读档也需要奇怪的暗号,才能解开之前存档封印重新开始,规则如下:
对一个长度为 n 的字符串 S,首先根据它构造 n 个字符串,其中第 i 个字符串由 S 向左循环移位 i-1次得到(见示例)。然后把这 n 个字符串按照首字符从小到大排序。如果两个字符串的首字符相同,则它们的相对位置不变。接着把排序后的字符串的尾字符依次连成一个新的字符串 S’。它的长度仍为 n,而且显然是 S 中的字符的一种重排。
例如:
S = example
1、构造 n 个字符串:
example
xamplee
ampleex
mpleexa
pleexam
leexamp
eexampl
2、将字符串排序:
ampleex
example
eexampl
leexamp
mpleexa
pleexam
xamplee
3、结果:
S’ = xelpame
p = 7
S’就是接触封印的字符串,S 的首字符在 S’中的序号 p
数据输入
输入包含两行。第一行为一整数 n,1<=n<=10000,表示 S 的长度;第二行为字符串
S,字符串全部由小写字母组成,没有其它字符。
数据输出
输出两行,第一行为 S’,第二行为整数 p。
输入示例
7
example
输出示例
xelpame
7
解题思路
用结构体来存每个字符串的 首字母 和 末字母(边读边存),并把原字符串的第一个元素做标记(因为题目保证只有小写字母,故可标记为大写字母),方便后续查找。然后用stable_sort对首字母排序,相应的输出末字母,如果末字母是大写字母的话,就说明找到位置 p
参考代码
#include <cstdio>
#include <cctype>
#include <algorithm>
const int maxn = 10010;
using namespace std;
struct P{
char c;
char last;
}str[maxn];
bool cmp(const P& s1,const P& s2){
return tolower(s1.c) < tolower(s2.c);
}
int main()
{
int n,i,p = 0;
while (~scanf("%d",&n)){
getchar();
for (i = 0;i < n;i++){
scanf("%c",&str[i].c);
if (i)
str[i].last = str[i-1].c;
else
str[0].c -= 'a'-'A'; //首字母转换成大写字母
if (i == n-1)
str[0].last = str[n-1].c;
}
stable_sort(str,str+n,cmp);
for (i = 0;i < n;i++){
printf("%c",tolower(str[i].last));
if (isupper(str[i].last)) //找到p
p = i+1;
}
printf("\n%d\n",p);
}
return 0;
}