Death to Binary? POJ - 2116 (A+B,模拟,训练比赛化)

传送门

题意:多组输入,每组输入两个01串表示的数a,b。要求表示a+b=c。

  • a,b之多40位
  •  Fibonacci进制:  。从低位到高位,权值分别为1,2,3,5,8,13,,,,,,

题解:就是个模拟a+b。这种模拟题要注意,一半很容易出先小错误。

  • 特别注意:a,b可能等于"0"。

收获:训练比赛化——做题的时候不用太考虑每一步骤是怎么出来的,AC算完事儿。之后再来总结。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#define int long long
#define read(x) scanf("%lld", &x)
#define print(a, c) printf("%lld%c", a, c)
#define dbg(x) cout << #x << "===" << x << endl;
#define pb push_back
using namespace std;
const int N = 40 + 10;

char a[N], b[N], c[N];
int fib[N];
int lena, lenb, lenc;
void init(int n) {
    fib[1] = 1, fib[2] = 2;
    for (int i = 3; i <= n; i++) fib[i] = fib[i - 1] + fib[i - 2];
    // fib[49]===12586269025
}
//这里无论是s[]还是*s传递的都是实参,数组的实际实际地址,所以调用函数之后如果在函数内改变数组那么函数外数组也是会变的。
//之前一直没注意,可能是因为并没有改变数组,而只是使用了数组的值
void update(int x, char *s) {
    int f = 0, len = 0;
    for (int i = 45; i >= 1; i--) {
        if (!f && fib[i] > x)
            continue;
        else if (!f)
            f = 1, len = i, s[i + 1] = '\0';
        if (fib[i] > x)
            s[len - i + 1] = '0';
        else
            s[len - i + 1] = '1', x -= fib[i];
        // cout << x << " " << i << " " << s[len - i + 1] << endl;
    }
    if (len == 0) s[1] = '0', s[2] = '\0';  // x为0的情况
}
void Print() {
    lenc = strlen(c + 1);
    int len = lenc + 2;
    lena = strlen(a + 1), lenb = strlen(b + 1);  //注意长度改变
    //为什莫要找出bug,而不是过了样例就交,因为这样你才知道错在哪里,样例很可能只是恰好对了
    for (int i = 1; i <= len - lena; i++) putchar(' ');
    puts(a + 1);

    putchar('+');
    for (int i = 2; i <= len - lenb; i++) putchar(' ');
    puts(b + 1);

    putchar(' '), putchar(' ');
    for (int i = 3; i <= len; i++) putchar('-');
    puts("");

    putchar(' '), putchar(' ');
    puts(c + 1);

    puts("");
}
signed main() {
    init(N - 1);
    while (cin >> a + 1 >> b + 1) {
        //转化为10进制
        int A = 0, B = 0;
        lena = strlen(a + 1), lenb = strlen(b + 1);
        for (int i = 1; i <= lena; i++)
            if (a[i] == '1') A += fib[lena - i + 1];
        for (int i = 1; i <= lenb; i++)
            if (b[i] == '1') B += fib[lenb - i + 1];

        int C = A + B;  //答案的十进制形式
        // a,b,c转化为fib进制形式
        update(A, a);
        update(B, b);
        update(C, c);

        Print();
    }
    return 0;
}
/*
input:::
11101 1101
1 1
output:::
   100101
+   10001
  -------
  1001000

   1
+  1
  --
  10
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值