zoukankan      html  css  js  c++  java
  • acwing2058. 笨拙的手指

    奶牛贝茜正在学习如何在不同进制之间转换数字。
    但是她总是犯错误,因为她无法轻易的用两个前蹄握住笔。
    每当贝茜将数字转换为一个新的进制并写下结果时,她总是将其中的某一位数字写错。
    例如,如果她将数字 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;
        }
    }
    
  • 相关阅读:
    【训练】9.13 训练赛
    【训练】9.12 训练赛
    【题录】CF#666 Div.2
    【题解】JSOI2009球队收益 / 球队预算
    【申明】——暂别博客园——
    【题解】CF#896 D-Nephren Runs a Cinema
    【题解】洛谷P4707重返现世
    [HNOI2012][BZOJ2732] 射箭 [二分+半平面交]
    平面几何-学习笔记
    [NOI.AC省选模拟赛3.31] 星辰大海 [半平面交]
  • 原文地址:https://www.cnblogs.com/nosae/p/15805829.html
Copyright © 2011-2022 走看看