数组A的子集,如果我们对该子集的所有元素执行AND,则输出应为2的幂

我得到了这个问题的解决方案:

给定一个数组A.是否存在数组A的任何子集,如果我们对该子集的所有元素执行AND,则输出应该是2的幂(例如:1,2,4,8,16等等)。

输入:第一行包含多个测试用例T.每个测试第一行包含N个数组A,下一行包含N个空格分隔的整数。

输出:对于每个测试用例,如果存在arraysA的任何子集,则打印YES,如果我们对该子集的所有元素执行AND,则输出应该是其他两个打印NO的幂。

解决方案是这样的,但我无法理解下面的解决方案。 请帮忙。

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = br.readLine(); int N = Integer.parseInt(line); for (int i = 0; i < N; i++) { int num = Integer.parseInt(br.readLine()); int[] arr = new int[num]; String arrCnts = br.readLine(); String[] arrStr = arrCnts.split(" "); boolean flag = false; int max = Integer.MIN_VALUE; for(int j = 0; j < num; j++) { arr[j] = Integer.parseInt(arrStr[j]); if(max < arr[j]) { max = arr[j]; } } int len = (int) (java.lang.Math.log10(max) / java.lang.Math.log10(2)); for (int k = 0; k <= len; k++) { int mask = 1 << k, mul = -1;//ffffffff for (int j = 0; j < num; j++) { if ((arr[j] & mask) != 0) { if (mul == -1) mul = arr[j]; else mul &= arr[j]; } } if (mul == -1) continue; else if (mul == mask) { flag = true; break; } } if(flag) { System.out.println("YES"); } else { System.out.println("NO"); } } SAMPLE INPUT 2 3 1 2 3 2 10 20 SAMPLE OUTPUT YES NO 

该算法的基本思想是:

让我们注意A_i是A的所有元素的集合,它们在二进制表示的第i个位置有’1’。 如果A的子集S = {s1,…,sn}使得AND(s1,… sn)= 2 ^ i = 100 … 0二进制(i零),那么AND的A_i的所有元素都等于2 ^ i,因为S必须是A_i的子集。

该算法所做的是计算A_i元素的AND,对于i从0len ,用于写入最大数量A减去1的位数。为此,它使用一个名为mask ,等于2 ^ i for i0len 。 然后,对于A中的每个数字,它通过进行测试(arr[j]&mask)!=0来检查该数字是否在第i个位置具有1。 如果是这种情况,它会更新mul ,最初只是所有的,使用带有mularr[j]的AND。

在内循环的末尾, mul包含A_i元素的AND。 如果对于某些imask==mul ,则存在满足该属性的子集,否则不存在这样的子集。