原题见
P2415 集合求和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
此题有三种大致思路。
思路一:首先每个元素在子集中出现次数一定是相等的。对于集合,比如有两个元素的集合,只需在剩下n-1个中再找1个,其个数有个。在所有子集中,有从1到总数个元素的集合。所以对于原集合中每一个元素有
个。通过性质可知该值等于2的n-1次方。
思路二:用二进制。比如说有4个数,那么0000代表空集,1111代表和原来集合一样的子集。然后从0到2的n次方,以0101为例,假设原集合存于数组array中,那么该子集结果等于array[0]*1+array[1]*0+array[2]*1+array[3]*0。把所有子集结果加起来就行。
思路三:留个坑。
以下代码为思路1代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//给出一个元素个数不超过 30 的集合,元素为 [1,10^8][1,10 8]范围内的整数,求该集合所有子集的元素之和。
int main(int argc, char** argv) {
//先把所有存进去
int array[31];
int i = 0;
while(scanf("%d",&array[i])!=EOF){
i++;
}
int num = i;//保存总数
long long int sum = 1;//用于保存数出现的次数
/*
for(int k = 1;k < num; k++){//选几个与其组成子集
long long int temp1 = 1,temp2 = 1;
for(int j = 2;j <= k;j++){
temp1 = temp1 * j;
}
for(int j = 1,l = num - 1; j <= k;j++,l--){//选k个
temp2 = temp2 *l;
}
sum = sum + temp2/temp1;
}
*/
sum = pow(2,num-1);
long long int result = 0;
for(int i = 0;i < num;i++){
result = result + (long long int)array[i];
}
result = result * sum;
cout << (long long)result <<endl;
return 0;
}