MemSQL Start[c]UP 2.0 - Round 2 A

来源:互联网 发布:长沙网络外包公司 编辑:程序博客网 时间:2024/05/27 21:49

        题意:黄金进制。就是说每逢q=1.618...进一,这样的进制不方便像通常那样比较大小,比如11=100。问题就是输入两个数,比较他们的大小。

        思路:记q=1.618...,根据定义,q^n可以分解为aq+b,然后a和b的递推规律都是斐波那契数列。最朴素的算法是把q^n分解为aq+b,然后计算他们的十进制值,再比较,可惜精度不允许。然后想到比较a和b两个系数,但是由于没有大数模版写了一下就卡住了。最后突然发现,其实这数比较不需要计算q,也不需要斐波那契,知道第i-2位和i-1位为1可以向i位进位就可以了。。。解法是对两个数进行进位,注意不要出现2,也不要进位不完全。具体见程序:


#include <iostream>    #include <stdio.h>    #include <cmath>    #include <algorithm>    #include <iomanip>    #include <cstdlib>    #include <string>    #include <memory.h>    #include <vector>    #include <queue>    #include <stack>    #include <map>  #include <set>  #include <ctype.h>    #define INF 1000000000  #define ll long long#define max3(a,b,c) max(a,max(b,c))#define MAXN 100010using namespace std;  char num1[100010];char num2[100010];int main(){while(~scanf("%s%s",num1+2,num2+2)){int len1=strlen(num1+2);int len2=strlen(num2+2);len1+=2;len2+=2;//下面是为了数位对齐 int _max=max(len1,len2);int d=abs(len1-len2);if(len1>len2){for(int i=len1-1;i>=d;i--){num2[i]=num2[i-d];}for(int i=d;i>=0;i--){num2[i]=0;}}else if(len2>len1){for(int i=len2-1;i>=d;i--){num1[i]=num1[i-d];}for(int i=d;i>=0;i--){num1[i]=0;}}//字符的0 1不好处理,转换成数字0 1 for(int i=0;i<=_max;i++){if(num1[i]=='0')num1[i]=0;if(num1[i]=='1')num1[i]=1;}for(int i=0;i<=_max;i++){if(num2[i]=='0')num2[i]=0;if(num2[i]=='1')num2[i]=1;}//从高位开始进位,注意连环进位的情况 for(int i=2;i<=100004;i++){if(num1[i]&&num1[i-1]){num1[i]--;num1[i-1]--;num1[i-2]++;int k=i-2;while(k>=2){if(num1[k]&&num1[k-1]){num1[k]--;num1[k-1]--;num1[k-2]++;k-=2;}else{break;}}}}//for(int i=2;i<=100004;i++){if(num2[i]&&num2[i-1]){num2[i]--;num2[i-1]--;num2[i-2]++;int k=i-2;while(k>=2){if(num2[k]&&num2[k-1]){num2[k]--;num2[k-1]--;num2[k-2]++;k-=2;}else{break;}}}}//进位完后就可以比较,像通常的进制一样 for(int i=0;i<100010;i++){if(num1[i]>num2[i]){cout<<">"<<endl;break;}else if(num1[i]<num2[i]){cout<<"<"<<endl;break;}if(i==100009)cout<<"="<<endl;}memset(num1,0,sizeof(num1));memset(num2,0,sizeof(num2));}return 0;}


0 0