无法理解按位运算的用法

时间:2014-12-26 08:39:29

标签: c++ bit-manipulation

来自dec long contest(codechef)的问题, - http://www.codechef.com/problems/SANSKAR, 我们只需要判断具有差异权重的n个实体是否可以划分给定的部分,每个部分具有相同的wt。 我没有得到AC,所以看了一个解决方案 - http://ideone.com/3hB8lI, 这个解决方案使用按位运算来简化问题,我知道按位操作,但不能得到这个解决方案中使用的方法,我知道复制odrs代码不是一个好主意,但我想知道如何在解决方案中使用按位运算得到答案..

#include<stdio.h>
int main() {
    int T, N, K;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &N, &K);
        long long a[N];
        for(int i=0; i<N; i++)
            scanf("%lld", &a[i]);
        long long totSans=0;
        for(int i=0; i<N; i++)
            totSans+=a[i];
        long long eachSans;
        if(N<K || totSans%K) {
            printf("no\n");
            continue;
        }
        if(totSans%K==0)
            eachSans=totSans/K;
        long long takeAll=0;
        int cnt=0;
        for(int i=0; i<(1<<N); i++) {
            long long sum=0;
            for(int j=0; j<N; j++)
                if(i & (1<<j))
                    sum+=a[j];
            if(sum==eachSans && !(i & takeAll)) {
                takeAll |= i;
                cnt++;
            }
        }
        printf(!totSans || cnt>=K ? "yes\n" : "no\n");
    }
}

1 个答案:

答案 0 :(得分:0)

for(int i=0; i<(1<<N); i++)用于组合: 它从0b00000循环到0b11111

以下代码:

long long sum=0;
for(int j=0; j<N; j++)
    if(i & (1<<j))
        sum+=a[j];
}

根据之前的'掩码'得到总和: 因此,对于i == 0b1010,sum将为a[1] + a[3](掩码索引从右侧开始)。