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}\) 的字典序顺序。

posted @ 2020-07-14 16:27  ice--cream  阅读(249)  评论(0编辑  收藏  举报