Luogu洛谷 P1036选数

题目

题目链接

Luogu洛谷P1036 选数

题解

这道题实际上是子集枚举的问题。

把n个数都存到1个数组里,那么需要枚举的是元素数量为k的子集,最求和判断是否为素数就可以。

子集枚举时候用2进制来表示每个元素的状态,1表示被选中,0表示未被选中。

n=4时,表示4个元素都被选中就是\(u=(1<<n)-1\)

现在一个子集\(s=1011B\),如何检测第\(i(i\ge 0)\)个元素是否在子集中?
通过\(s \& (1<<i)\)来检测。这样做与运算,只有同为1才能返回1。

内建函数__builtin_popcount()可以返回二进制中1的数量。

所以程序思路为:枚举子集,当子集元素数量等于k时候,求和并检查是否为素数。

Then show the code.

#include <cstdio>
#include <iostream>

int n, k, x[30], sum, cnt;

bool check(int a){
    for(int i=2; i*i<=a; i++){
        if(a%i == 0) return 0;
    }
    return 1;
}

int main(){
    scanf("%d%d", &n, &k);
    for(int i=0; i<n; i++)
        scanf("%d", &x[i]);
    int u = (1<<n)-1;
    for(int s=0; s<=u; s++){
        if(__builtin_popcount(s) == k){
            sum = 0;
            for(int i=0; i<n; i++)
                if(s & (1<<i)) sum += x[i];
            if(check(sum)) cnt++;
        }
    }
    printf("%d", cnt);
    return 0;
}
posted @ 2021-01-28 17:18  1v7w  阅读(72)  评论(0编辑  收藏  举报