其他分享
首页 > 其他分享> > acwing-2058. 笨拙的手指

acwing-2058. 笨拙的手指

作者:互联网

奶牛贝茜正在学习如何在不同进制之间转换数字。
但是她总是犯错误,因为她无法轻易的用两个前蹄握住笔。
每当贝茜将数字转换为一个新的进制并写下结果时,她总是将其中的某一位数字写错。
例如,如果她将数字 14 转换为二进制数,那么正确的结果应为 1110,但她可能会写下 0110 或 1111。
贝茜不会额外添加或删除数字,但是可能会由于写错数字的原因,写下包含前导 0 的数字。
给定贝茜将数字 N 转换为二进制数字以及三进制数字的结果,请确定 N 的正确初始值(十进制表示)。

输入格式

第一行包含 N 的二进制表示,其中一位是错误的。
第二行包含 N 的三进制表示,其中一位是错误的。

输出格式

输出正确的 N 的值。

数据范围

0≤N≤10^9,且存在唯一解。

输入样例:

1010
212

输出样例:

14

样例解释

14 在二进制下的正确表示为 1110,在三进制下的正确表示为 112。

本质:遍历所有出错组合

方法一:遍历每种出错的可能

比如样例共有4*3种可能,复杂度=n^2

#include <bits/stdc++.h>
using namespace std;
int main() {
    string s1, s2;
    scanf("%s%s", &s1, &s2);
    int i, j;
    unsigned int num1 = 0, num2 = 0;
    unsigned int r = 1;
    for (i = s1.length() - 1; i >= 0; i--) {
        num1 += r * (s1[i] - '0');
        r <<= 1;
    }
    r = 1;
    for (i = s2.length() - 1; i >= 0; i--) {
        num2 += r * (s2[i] - '0');
        r *= 3;
    }
    unsigned int r2; r = 1;
    for (i = s1.length() - 1; i >= 0; i--) {
        int t = s1[i] - '0';
        if (t) num1 -= r; else num1 += r;
        r2 = 1;
        for (j = s2.length() - 1; j >= 0; j--) {
            for (int k = 0; k <= 2; ++k) {
                int u = s2[j] - '0';
                if(u == k) continue;
                num2 += (k - u) * r2;
                if (num1 == num2){
                    printf("%d", num1);
                    break;
                }
                num2 += (u - k) * r2;
            }
            r2 *= 3;
        }
        if (t) num1 += r; else num1 -= r;
        r <<= 1;
    }
}

方法二:借助unordered_set

借助unordered_set先记录所有可能的二进制数,在遍历三进制数时进行逐个对比

#include <bits/stdc++.h>
using namespace std;

// 秦九昭算法,仅限base<=10
int convert(string s, int base) {
    int res = 0;
    for (const auto &item : s)
        res = res * base + item - '0';
    return res;
}

int main() {
    string a, b;
    unordered_set<int> S;
    cin >> a >> b;
    for (auto &item : a) {
        item ^= 1; // 48->49 or 49->48
        S.insert(convert(a, 2));
        item ^= 1;
    }
    for (auto &item : b) {
        char t = item;
        for (char i = '0'; i < '3'; i++) {
            if (t == i) continue;
            item = i;
            int x = convert(b, 3);
            if (S.count(x)) {
                printf("%d", x);
                return 0;
            }
        }
        item = t;
    }
}

标签:笨拙,数字,二进制,int,2058,s1,item,进制,acwing
来源: https://www.cnblogs.com/nosae/p/15805829.html