51 Nod 1491 黄金系统

                           1491 黄金系统

q=(5√+1)2在黄金系统下面a0a1...an等于 ni=0aiqni ,其中 ai 是0或者1。

现在给出两个黄金系统下面的数字,请比较他们的大小。

Input
单组测试数据。
第一行有一个字符串A。
第二行有一个字符串B。
按照a0到an的顺序输入。
他们都是非空串,可能有前导0,并且只有0和1组成,长度不超过100000。
Output
如果A>B,输出>;
如果A=B,输出=;
如果A<B,输出<;
Input示例
00100
11
Output示例
=

思路:打个表 可以发现 qi 是一个类斐波那契数列
   因为字符串长度 最大到100000 所以 肯定会爆 long long
   既然是类斐波那契数列
   我们就有 qn == qn-1 *qn-2
    证明:
q2=(5+1)2/4=(5+1+25)/4=(3+5)/2=1+(1+5)/2=1+q 
      
所以n>=2qn=qn2q2=qn2(q+1)=qn1+qn2 
   我们可以用 f[i] 表示 qi 的系数
   我们可以用 1 表示 字符串a的第 i 位 存在 一个1
         -1 表示 字符串的b第 i 位 存在一个 1
   当字符串a的第 i 位上存在 1 的时候 ++f[n-i]
字符串b的第 i 位上存在 1 的时候 --f[n-i]
   再用来模拟从高位到低位进位 即 f[i]=f[i+1]+f[i+2];
   题目中的说法是 ∑ni=0(aiqni) 我程序中 f[i] = s[i] - '0' ;相当于把字符串倒叙映射
   因此 从高到低位 是 从 max( Len1, Len2)--> i==3

   全部转移到 f[1] 和 f[0] 上 再来判断大小
   这样就可以过了么 too young !! 会爆long long 的!!
   事实上 我们从高位向低位转移的的时候 当某一位上的绝对值大于 2 的时候 就已经比较出大小了  
   所以要在转移过程中判断大小
 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #define max(a,b) a<b?b:a
 5 
 6 const int MAXN=100010;
 7 
 8 int Len1,Len2;
 9 
10 char s[MAXN],v[MAXN];
11 
12 int f[MAXN];
13 
14 int hh() {
15     scanf("%s%s",s+1,v+1);
16     
17     double q=(sqrt(5)+1)/2;
18     Len1=strlen(s+1);Len2=strlen(v+1);
19     for(int i=1; i<=Len1; ++i) f[Len1-i]=s[i]-'0';
20     for(int i=1; i<=Len2; ++i) f[Len2-i]+='0'-v[i];
21     
22     for(int i=max(Len1,Len2); i>=3; --i) {
23         if(f[i]<-1) {printf("<
"); return 0;}
24         if(f[i]>1) {printf(">
"); return 0;}
25         f[i-1]+=f[i];
26         f[i-2]+=f[i];
27     }
28     f[1]+=f[2];f[0]+=f[2];
29     if(f[1]==0 && f[0]==0) printf("=
");
30     else {
31         double Ans=f[1]*1.0*q+f[0];
32         if(Ans>0) printf(">");
33         else printf("<
");
34     }
35     
36     return 0;
37 }
38 
39 int sb=hh();
40 int main(int argc,char**argv) {;}
代码


 
原文地址:https://www.cnblogs.com/whistle13326/p/7738759.html