东华大学 oj93——隐藏口令

问题描述 :
有时候程序员有很奇怪的方法来隐藏他们的口令。
Billy"Hacker"Geits会选择一个字符串S(由L个小写字母组成,5<=L<=100,000),然后他把S顺时针绕成一个圈。
如字符串cbadfa,绕成一个圈后,我们认为字符串首尾相连。
每次取其中一个字母作为起始字母,并顺时针依次取字母而组成一个字符串。这样将得到一些字符串。
比如字符串cbadfa,按照以上规则取出的字符串有:
cbadfa badfac adfacb dfacba facbad acbadf
我们找到最小的那个字符串,可知为acbadf,也可知道它的第一个字符’a’在原字符串cbadfa中为第6个字符(位置从1开始),
将得到的结果6减1得到5,这就是我们需要的口令。
再比如字符串alabala,绕成一个圈后,每次取其中一个字母作为起始字母,并顺时针依次取字母而组成一个字符串。这样将得到一些字符串:
alabala labalaa abalaal balaala alaalab laalaba aalabal
我们找到最小的那个字符串,可知为aalabal,它的第一个字母’a’在原字符串中位置为7,7-1=6,则6为口令。
注:如果按照规则有两个字符串都是最小的,则取前面那一个。

输入说明 :
第一行:一个数L
第二行及之后:字符串S。
注意:字符串S可跨多行,但其中的’\n’不算成S中的字符

输出说明 :
一行,为得到的口令。
无多余空格或空行。

输入范例 :
6
cbadfa

输出范例 :
5

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */


int cmp(int a,int b) {
	if(a<b) {
		return a;
	} else {
		return b;
	}
}

int rule(char str[],int L){
	int i = 0, j = 1,k=0;
	while (i < L && j < L && k < L) {
		k = 0;// 重新开始比较

		while (str[(i + k) % L] == str[(j + k) % L] && k < L){// 相等的情况
			++k;
		}
		if (k == L){
			break;
		}
		if (str[(i + k) % L] > str[(j + k) % L]) {// 前者比后者大的情况
			i += k + 1;
		} else {
			j += k + 1;
		}
		if (i == j) {// 处理位置重合的情况
			j++;
		}
	}
	
	return cmp(i,j);
}

int main(int argc, char *argv[]) {
	int L=0,i=0;
	char ch;
	char str[100002] = "";// 原始字符串

	scanf("%d", &L);
	getchar();// 吸收换行符
	while (i < L) {
		ch = getchar();
		if (ch != '\n'){
			str[i] = ch;
			++i;	
		}
	}
	str[i] = '\0';

	

	printf("%d\n", rule(str,L));

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值