C. Boboniu and Bit Operations
原题链接:https://codeforces.ml/contest/1395/problem/C
题目大意:
给两个数组$a,b$,每一个$a_i$可以和任何一个$b_i$组合求与运算得到$c_i$,需要求出$c_{1}left|c_{2} ight| ldots mid c_{n}$的最小值。
解题思路:
求或运算的时候每位上只要有一个1,得到的值的这一位就为1,要想得到的值最小就要要求最高位尽量为0,高位为0那么低位为何值也不会有比高位为1的情况大。所以可以逐为判断是否可以为0。
我的方法比较复杂。
首先开一个二维数组,$arr_{i,j}$代表与$a_i$匹配的第j个数的大小。初始时为都为序列b,逐位计算的时侯,如果能将第$i$位变为$0$则将所有让第i位变为$1$的都删掉,否则不变。
代码:
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 typedef pair<int,int> pi;
5 typedef complex <double> cp;
6 #define debug(a) cout<<#a<<":"<<a<<endl;
7 #define fr freopen("in.txt","r",stdin);
8 #define Fill(x,a) memset(x,a,sizeof(x))
9 #define cpy(a,b) memcpy(a,b,sizeof(a))
10 const double PI = acos(-1);
11 const int INF=0x3f3f3f3f;
12 const int N=1e3;
13 const int mod=1e9+7;
14 int maxn,minn;
15 int T,n,m,q;
16 int ans[N],a[N],b[N];
17 int arr[N][N];
18
19 int main(){
20 cin>>n>>m;
21 for(int i=1;i<=n;i++){
22 scanf("%d",a+i);
23 }
24 for(int i=1;i<=m;i++){
25 scanf("%d",b+i);
26 }
27 for(int i=1;i<=n;i++){
28 for(int j=1;j<=m;j++){
29 arr[i][j]=b[j];
30 }
31 }
32 int flag,len;
33 for(int i=8;i>=0;i--){
34 flag=0;
35 for(int j=1;j<=n;j++){
36 int gg=1;
37 for(int k=1;k<=m;k++){
38 if((((a[j]&arr[j][k])>>i)&1)==0){
39 gg=0;
40 break;
41 }
42 }
43 if(gg){
44 flag=1;
45 }
46 }
47 if(flag==1){
48 ans[i]=1;
49 }
50 else{
51 ans[i]=0;
52 for(int j=1;j<=n;j++){
53 for(int k=1;k<=m;k++){
54 if(((a[j]&arr[j][k])>>i)==1){
55 arr[j][k]=511;
56 }
57 }
58 }
59 }
60 }
61 int res=0;
62 int bit=1;
63 for(int i=0;i<=8;i++){
64 if(ans[i]){
65 res+=bit;
66 }
67 bit*=2;
68 }
69 cout<<res<<endl;
70
71
72 return 0;
73 }
74