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;
}

浙公网安备 33010602011771号