AcWing_2058 笨拙的手指(哈希,模板或unordered_set)

AcWing

2058. 笨拙的手指

数据量不大,枚举每一位改为正确的情况。对于二进制下枚举的结果,用哈希表h[N]存储(开二或三倍数据量的大小,最好是质数);对于三进制下枚举的结果,如果哈希表中已经存在,那么将其存入结果数组vector<int> res中。由于算法中答案有前导0的情况没有排除,最终的结果数组可能会有两个答案,一个包含前导0,一个不包含,只需取数值最大的一个即可。

#include <bits/stdc++.h>
using namespace std;
vector<int> res;
string a, b;
int changeBase(string str, int n){  // 秦九韶算法做进制转换
    int res = 0;
    for(int i = 0; i <= (int)str.size() - 1; i++){
        res = res * n + str[i] - '0';
    }
    return res;
}
const int N = 103;
// hash,模板
int h[N];   // hash表
int find(int a){    // 开放寻址法
    int p = a % N;
    while(h[p] != -1 && h[p] != a){
        if(++p == N) p = 0;
    }
    return p;   // 第一个空位或a所在的位置
}
int main(){
    cin >> a >> b;
    memset(h, -1, sizeof h);
    // fill(h, h + 103, -1);
    for(int i = 0; i <= (int)a.size() - 1; i++){
        string sp = a;
        sp[i] ^= 1; // ascii: '0':48->'1':49, '1':49->'0':48
        int deci = changeBase(sp, 2);
        h[find(deci)] = deci;
    }
    for(int i = 0; i <= (int)b.size() - 1; i++){
        for(int j = 0; j <= 2; j++){
            string sp = b;
            if(sp[i] - '0' != j) sp[i] = j + '0';
            int deci = changeBase(sp, 3);
            if(h[find(deci)] != -1) res.push_back(deci);
        }
    }
    if((int)res.size() == 1) cout << res[0] << endl;
    else cout << *max_element(res.begin(), res.end()) << endl;
    return 0;
}