记得读档

实验任务

小光头找到小菇凉存档后遇到了意外,需要重新开始。可是读档也需要奇怪的暗号,才能解开之前存档封印重新开始,规则如下:

对一个长度为 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;      
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值