Infinite String Comparision
题目描述
For a string \(x\) ,Bobo define \(x^{\infty}\) =xxx,,,which is x repeats for infinite times ,resulting in a string of infinite length. Bobo has two strings a and b. Find out the result comparing \(a^{\infty}\) and \(b^{\infty}\) in lexicographical order. You can refer the wiki page further information of Lexicographical Order.
输入描述
The input consist of several test cases terminated by end - of - file .
The first line of each test cases contains a string a,and the second line contains a string b
- 1≤|a|, |b|≤\(10^{5}\)
- a, b consists of lower case letters
- The total length of input strings does not exceed 2 x \(10^{6}\)
输出描述
For each test cases , print "=" ,if \(a^{\infty}\) = \(b^{\infty}\) , otherwise, print "<",if \(a^{\infty}\) < \(b^{\infty}\) ,or ">",if \(a^{\infty}\) > \(b^{\infty}\)
示例一
输入
aa
b
zzz
zz
aba
abaa
输出
<
=
>
题解
#include <cstdio>
#include <cstring>
static const int N = 100000;
//求最大公约数
template <typename T>
T gcd(T a, T b){
return b ? gcd(b, a % b) : a;
}
int main() {
//存放两个字符串
static char a[N + 1], b[N + 1];
//读到EOF为止
while (scanf("%s%s", a, b) == 2) {
//取出两个串的长度
int alen = strlen(a);
int blen = strlen(b);
//如果超出maxlen还相等,那么这两个字符串相等
int maxlen = alen + blen - gcd(alen, blen);
char result = '=';
//开始遍历,只要出现字符不相等的情况,就跳出,并输出大于小于号
for (int i = 0; i < maxlen && result == '='; ++i) {
char ai = a[i % alen];
char bi = b[i % blen];
if (ai != bi) {
result = ai < bi ? '<' : '>';
}
}
//输出结果
printf("%c\n", result);
}
}
思路:
关于周期性引理,定理内容:
假设一个字符串\(S\)有循环节\(P\)和\(q\)并且满足\(p+q≤|S|+gcd(p,q)\),那么\(gcd(p,q)\)也是一个循环节。
在本题中,只有当\(a^{\infty}\) = \(b^{\infty}\) 时,才用得到这个周期引理,比如说,第一个字符串为ab,第二个字符串为abab,这样\(a^{\infty}\) 就等于\(b^{\infty}\)了,这时候,公式中的字符串S就是\(a^{\infty}\) 或\(b^{\infty}\) ,事实上,此时\(a^{\infty}\)和\(b^{\infty}\)这两个字符串本身就完全一样,就是同一个字符串。这时候,ab长度为2,2是字符串S的一个循环节,abab长度为4,4也是字符串S的一个循环节,我们假设p=2,q=4.因为在题意中,字符串是无限接合在一起的,所以字符串的长度是无穷,所以|S|是无穷,所以任何情况下,不论p、q为多少,\(|S|≥p+q-gcd(p,q)\) 都是成立的,如果这个条件成立,也就是说gcd(p,q)此时就是一个循环节,那么我们还知道,在一个字符串中,一定存在最小循环节,比最小循环节大的循环节一定是最小循环节的倍数。那么此时,p是循环节,q是循环节,gcd(p,q)也是循环节,因为他们都是最小循环节的倍数,所以他们运算的结果也是最小循环节的倍数,也就是说,p+q-gcd(p,q)也是一个循环节,所以当比较字符串比较了p+q-gcd(p,q)次时,还没有出现不相同的字符,那就不用再比较了,因为再比较也是一样的结果,只会再循环一次前面的字符,所以此时我们就可以判断两个字符串是相等的了。
当\(a^{\infty}\) 不等于\(b^{\infty}\) 的时候,就用不到这个周期引理,比如说,第一个字符为aba,长度为3,设p为3,第二个字符为ab,长度为2,设q为2,因为\(a^{\infty}\) 根本就不等于\(b^{\infty}\) 所以,p和q也没办法是字符串S的循环节,这时的字符串S也不是唯一确定的,只能说p是第一个字符串的循环节,q是第二个字符串的循环节,但他们并没有什么关系,所以这时候用不到周期性引理。但是,我们还是要看一下p+q-gcd(p,q)在\(a^{\infty}\)和\(b^{\infty}\) 不相等的情况下有没有什么意义,经过多次测试,我发现,p+q-gcd(p,q)的结果总是等于p和q中较小的数的倍数,并且一定大于p和q中较大的数。这个证明我不会证,不过试了很多次这句话都成立,我觉得应该是有这么回事的。这里我们设p+q-gcd(p,q)的结果为W,p和q中较小的数是p,较大的数是q,那么W是p的倍数,在我们这个题里边,不就是相当于a字符串的很多次方后的长度是W吗(这里,p代表a的长度),而这个W大于q,也就是大于b字符串的长度,那么如果两个字符串不相等,一定会在比较W次之前就出现不相同的字符,如果两个字符串相同,在比较W次之前,也不会出现不同的字符(当然,W次之后也不会出现不同的字符),这样,还与\(a^{\infty}\)和\(b^{\infty}\) 相等时的情况相呼应了。
这样的话,我们只要比较p+q-gcd(p,q)次就行了,这样就能判断两个字符串是不是相等。经历过这道题,我们就可以直接得出结论:如果有两个字符串a和b,他们的长度分别为p和q,那么只要比较p+q-gcd(p,q)次,就可以得知\(a^{\infty}\) 和\(b^{\infty}\) 的字典序顺序。