1、加入数字x到集合中。
2、询问集合中是否存在一个子集,满足子集中所有数字的Or值恰好为k。
Or为二进制按位或操作,C++中表示为"|"。小易希望你能解决这个问题。
第一行数字q,表示操作个数
接下来q行,每行两个数字:
1 x表示插入数字x2 x表示询问数字x(即题设中询问的数值k), 。
对于每个询问,输出"YES"或者"NO"表示是否存在。
9 1 4 2 5 1 9 1 15 2 4 1 11 2 10 2 7 2 9
NO YES NO NO YES
import sys def main(): def exist(x): y = 0 for i in lst: if i | x == x: y |= i if x == y: return True else: return False lst = set() res = [] q = int(sys.stdin.readline().strip()) m = map(int, sys.stdin.read().split()) xlst = list(zip(m, m)) for i, j in xlst: if i == 1: lst.add(j) else: res += ['YES' if exist(j) else 'NO'] print(*res, sep='\n') if __name__ == '__main__': main()Python玩这种题就是亏,只能过60%
#include <iostream> #include <string> #include <vector> using namespace std; bool isexist(vector<int> temp,int x) { int y = 0; for (int i = 0; i < temp.size(); i++) { if ((x | temp[i]) == x) y = y | temp[i]; } return x == y; } int main() { int n; cin >> n; vector<int> temp; while (n--) { int a, x; cin >> a >> x; if (a == 1) temp.push_back(x); else { if (isexist(temp, x)) cout << "YES" << endl; else cout << "NO" << endl; } } system("pause"); return 0; }
#python3 try: data = [] ks = [] q = int(input()) n = 1 while n <= q: temp = [] insert = list(input().split(" ")) x = int(insert[0]) k = int(insert[1]) if x == 1: temp = [] data.append(k) ks.append(k) ks = list(set(ks)) if len(data) != 1: for i in range(len(ks)): temp.append(ks[i] | k) for i in range(len(temp)): ks.append(temp[i]) ks = list(set(ks)) if x == 2: flag = 0 for i in range(len(ks)): if ks[i] == k: flag = 1 break if flag: print("YES") else: print("NO") except: pass
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int q = sc.nextInt(); Set<Integer> set = new HashSet<>(); while(q-->0){ int flag =sc.nextInt(),target=sc.nextInt(); if(flag==1){set.add(target);} else{ int temp=0; for(Integer each:set){ if((each&target)==each){ temp|=each; } if(each==target){temp=target;break;} if(target==temp)break; } if(temp==target){ System.out.println("YES"); set.add(target); } else System.out.println("NO"); } } } } 就通过60
难点就是:怎么在一个集合 a 中判断是否存在一个子集,使得子集中所有元素 或运算后的结果为 x
暴力想法
找到集合a中的所有子集,然后一一判断是否满足条件。
子集个数一共有2^n,n为集合元素个数。所以肯定超时
优化
有没有可能遍历一遍集合,就可以完成。
假设元素 x 的二进制为 100100101
如果存在a1 | a2 | a3 | 。。。 | an = x
根据 | 的特点,
0 | 0 = 0,
1 | 0 = 1,
0 | 1 = 1,
1 | 1 = 1
如果我x的倒数第二位是0,那么a1, a2,…,an的倒数第二位肯定不能为1
所以,需要满足a1 | x = x, a2 | x = x,可以用反证法证明。
#include <bits/stdc++.h> using namespace std; const int N = 100010; bool st[N]; int q, o, x; int main() { scanf("%d", &q); vector<int> a; while (q --) { scanf("%d%d", &o, &x); if (o == 1) { if (st[x] == false) a.push_back(x); st[x] = true; } else { int y = 0; for (int v : a) { if ((v | x) == x) y |= v; } if (y == x) { printf("YES\n"); } else { printf("NO\n"); } } } return 0; }
a1=int(input()) a=[] for i in range(a1): a.append(list(map(int, input().split()))) fun1(a) def fun1(a): global ar1 ar1=[] for i in range(len(a)): if a[i][0]==1: charu(a[i][1]) elif a[i][0]==2: chaxun(a[i][1]) def charu(x1): ar1.append(x1) def chaxun(x2): for i in range(1,len(ar1)+1): for j in combinations(ar1,i): a=j[0] for k in range(1,len(j)): a=a|j[k] if x2==a: break if x2==a: break if x2==a: print("YES") else: print("NO")python方便很多
public class solution1 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = sc.nextInt(); int[] arr = new int[a]; int i = 0; while(a>0) { int b = sc.nextInt(); if(b == 1){ arr[i] = sc.nextInt(); i++; }else{ int c = sc.nextInt(); int sum = 0; int j =0; for(;j<arr.length;j++) { if ((c | arr[j]) - c == 0) { sum = sum | arr[j]; if (sum == c) { System.out.println("YES"); break; } } else { continue; } } if(j == arr.length) System.out.println("NO"); } a--; } } }
#include<bits/stdc++.h> using namespace std; vector<int> v; // 因为是按位或,对于待判断的数字中,若一位为1,则集合中所有数字,只要有一个这一位为1即可 // 如果完全能匹配上,就是存在 bool ifExist(int x){ int y=0; for(int i=0;i<v.size();i++){ if((x|v[i])==x){ y = y|v[i]; } } return x==y; } int main(){ vector<bool> ans; int n; scanf("%d",&n); for(int i=0;i<n;i++){ int o,x; scanf("%d%d",&o,&x); if(o==1) v.push_back(x); else{ if(ifExist(x)) ans.push_back(true); else ans.push_back(false); } } for(int i=0;i<ans.size();i++){ ans[i]?printf("YES\n"):printf("NO\n"); } return 0; }