2024.11.2 CW 模拟赛

题面 & 题解

T1

题面让我们求一个排列 \(p\), 使得 \(a_i \oplus b_{p_i} = x\), 其中每一个 \(x\) 均相等, 最后升序输出每一个 \(x\).

不难发现, \(x\) 只可能是 \(a_1 \oplus b_i\). (当然, \(a_1\) 可以是序列 \(a\) 中的其他数)

故我们可以枚举每一个可能的 \(x\) (即 \(a_1 \oplus b_i\)), 然后判断是否合法即可.

时间复杂度 \(\mathcal{O}(n^2 \log n)\) (我用的 \(multiset\), 用哈希表可以做到 \(\mathcal{O}(n^2)\)).

#include "iostream"
#include "algorithm"
#include "set"

using namespace std;

const int N=2e3+10;

int n;
int a[N],b[N];

int main(){

#ifdef FILE_IO
    freopen("f.in","r",stdin);
    freopen("f.out","w",stdout);
#endif

    scanf("%d",&n);
    for (int i=1;i<=n;++i) scanf("%d",a+i);
    for (int i=1;i<=n;++i) scanf("%d",b+i);

    if (n<=10){
        int p[11],x;
        bool f=1;
        set<int> ans;
        for (int i=1;i<=n;++i) p[i]=i;

        x=a[1]^b[p[1]];
        
        for (int i=2;i<=n;++i)
            if (x!=(a[i]^b[p[i]])){
                f=0;
                break;
            }
        if (f) ans.insert(x);

        while (next_permutation(p+1,p+n+1)){
            f=1,x=a[1]^b[p[1]];
            
            for (int i=2;i<=n;++i){
                if ((a[i]^b[p[i]])!=x){
                    f=0;
                    break;
                }
            }

            if (f) ans.insert(x);
        }

        printf("%d\n",ans.size());
        for (int x:ans) printf("%d\n",x);
    }
    else{
        set<int> ans;
        multiset<int> s;
        for (int i=1;i<=n;++i){
            s.clear();
            for (int j=1;j<=n;++j) if (j!=i) s.insert(b[j]);
            
            int x=a[1]^b[i];
            bool f=1;

            for (int j=2;j<=n;++j){
                if (s.find((x^a[j]))==s.end()){
                    f=0;
                    break;
                }
                s.erase((x^a[j]));
            }
            if (f) ans.insert(x);
        }

        printf("%d\n",ans.size());
        for (int x:ans) printf("%d\n",x);
    }

    return 0;
}
posted @ 2025-02-21 10:56  Steven1013  阅读(20)  评论(0)    收藏  举报