zoukankan      html  css  js  c++  java
  • 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
    ", 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}) 的字典序顺序。

  • 相关阅读:
    【codeforces 723F】stSpanning Tree
    struts2.0中struts.xml配置文件详解
    存储过程中调用JAVA程序段
    本不该逃避
    利用js实现对页面的自动刷新
    [转]从硬盘安装 RedHat Enterprise Linux Server 5 iso
    正则表达式使用
    利用XmlBean轻松读写xml(转)
    Struts2+Spring2+Hibernate3 web应用示例(七)
    在DWR中实现直接获取一个JAVA类的返回值的两种方法
  • 原文地址:https://www.cnblogs.com/fate-/p/13299779.html
Copyright © 2011-2022 走看看