POJ 2116 Death to Binary?(模拟题)

题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/T
题目大意:
读入两个01串,分别表示两个数X,Y
比如1101001表示 Fib = F0 + F3 + F5 + F6 = 1 + 5 + 13 + 21 = 40.
求这两个数的和,同样用01串表示结果 最后输出一个加法算式
如11101 1101
输出:
100101
+ 10001
- - - - - - -
1001000
假设三个串长度分别为len1,len2,len3
第一行:先输出len3+2-len1个空格,再输出第一个串
第二行:先输出一个加号,再输出len3+1-len2个空格,再输出第二个串
第三行:先输出两个空格,再输出len3个 字符
第四行:先输出两个空格,再输出第三个串

注意:
1.输入的串可能有前导零
2.可能有0 0 这样的极端数据
3.输入的两个串也需要处理,样例里没有给出,但是题意里有
比如输入111应该输出 1001

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include <algorithm>
#define mod 1000000007
using namespace std;
typedef long long ll;
ll n,ans,y;
ll Fb[100];
void init()
{
    Fb[0]=1;
    Fb[1]=2;
    for (int i = 2; i <= 44 ; i ++)
        Fb[i]=Fb[i-1]+Fb[i-2];
}

char s1[100],s2[100],s3[100];
int main()
{
    init();
    ll n1,n2;
    while (~scanf("%s%s",s1,s2))
    {
        n1=n2=0;
        int l1 = strlen(s1),l2=strlen(s2);
        for (int i = l1 -1  ; i >= 0 ; --i )
        {
            if (s1[i]=='1')
                n1 += Fb[l1-1-i];
        }
        for (int i = l2 -1  ; i >= 0 ; --i )
        {
            if (s2[i]=='1')
                n2 += Fb[l2-1-i];
        }
        ll ans = n1 + n2 ,tmp;
        {
            tmp = 0;
            int pos = lower_bound(Fb,Fb+45,n1)-Fb;
            if (Fb[pos]>n1) pos--;
            //printf("now pos = %d\n",pos);
            if (pos==-1)
            {
                s1[0]='0';
                pos= 0;
            }
            for (int i = pos ; i >=0 ; --i)
                if (tmp+Fb[i]<=n1)
                {
                    s1[pos-i]='1';
                    tmp += Fb[i];
                }
                else
                    s1[pos-i]='0';

            s1[pos+1]='\0';
            l1 = strlen(s1);
        }
        {
            tmp = 0;
            int pos = lower_bound(Fb,Fb+45,n2)-Fb;
            if (Fb[pos]>n2) pos--;
            //printf("now pos = %d\n",pos);
            if (pos==-1)
            {
                s2[0]='0';
                pos= 0;
            }
            for (int i = pos ; i >=0 ; --i)
                if (tmp+Fb[i]<=n2)
                {
                    s2[pos-i]='1';
                    tmp += Fb[i];
                }
                else
                    s2[pos-i]='0';

            s2[pos+1]='\0';
            l2 = strlen(s2);
        }
        tmp = 0;
        int pos = lower_bound(Fb,Fb+45,ans)-Fb;
        if (Fb[pos]>ans) pos--;
        //printf("now pos = %d\n",pos);
        if (pos==-1)
        {
            s3[0]='0';
            pos= 0;
        }
        for (int i = pos ; i >=0 ; --i)
            if (tmp+Fb[i]<=ans)
            {
                s3[pos-i]='1';
                tmp += Fb[i];
            }
            else
                s3[pos-i]='0';

        s3[pos+1]='\0';
        int l3 = strlen(s3);
        for (int i = 1 ; i <= l3+2 - l1 ; i ++)
        putchar(' ');
        printf("%s\n",s1);
        putchar('+');
        for (int i = 1 ; i <=l3+1-l2;i++)
            putchar(' ');
        printf("%s\n",s2);
        printf("  ");
        for (int i = 1; i <= l3;i ++)
            putchar('-');
        putchar('\n');
        printf("  ");
        printf("%s\n\n",s3);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值