hdu 6477 数据恢复·set

题解

bi^ k = ai
b ^ k ^ k = a ^ k
b = a ^ k

暴力做法:
统计所有a与b之间可能出现的k,找到最小的那个

看了眼范围,觉得会T,就放弃了暴力

然后想了想,这个最小的k肯定出现在a[1]和所有的b异或得出的结果里,

对a[1]和所有的b异或得出的结果从小到大排序,
检验 k[i] 与 a[ 2 ~ n ] 异或产生的b是否存在于原b序列中,

到这里已经套了两个for了,很明显判断b是否存在不可以再for一遍,TLE警告

第一反应二叉搜索树,再稳定一点,就是平衡树,二分好像也可以,没试过
前几天刚学到的set(红黑树)可以拿来用了,

一旦符合,直接输出


在这里插入图片描述


#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],b[N],k[N];
int n,m;
set<int>s;
int main(){
    ios::sync_with_stdio(0);

    int T;
    cin>>T;
    for (int cs = 1; cs <= T; ++cs) {
        s.clear();

        cin>>n;
        for (int i = 1; i <= n; ++i) {
            cin>>a[i];
        }
        for (int i = 1; i <= n; ++i) {
            cin>>b[i];
            k[i]=a[1]^b[i];
            s.insert(b[i]);
        }
        sort(k+1,k+1+n);
        int cnt=unique(k+1,k+1+n)-k-1;//去重 

        for (int i = 1; i <= n; ++i) {
            bool f=true;
            for (int j = 2; j <= n; ++j) {
                int t=a[j]^k[i];
                if(s.find(t)==s.end()){//判断是否找到 如果没找到 s.find()==s.end()
                    f=false;
                    break;
                }
            }
            if(f) {
                cout<<k[i]<<endl;
                break;
            }
        }
    }
    return 0;
}
发布了43 篇原创文章 · 获赞 0 · 访问量 1246

猜你喜欢

转载自blog.csdn.net/Yubing792289314/article/details/104271628