Run ID 作者 问题 语言 测评结果 Time Memory 代码长度 提交时间
27637 唐心 求和比较 C++ Accepted 2 MS 728 KB 1442 2022-06-07 17:53:33

Tests(4/4):


Code:

/* 二进制枚举利用的是二进制下n位长度的数有2n个,一个有n个元素的集合子集个数也为2n个, 所以可以利用二进制的1,0和集合中的元素联系起来他可以实现组合也可以实现容斥 对一个二进制来说1代表取这个元素0代表不取这个元素,1和0所在的位置代表元素的位置, 这样的思想在有时候给题目有了很大的方便举个例子如集合{a,b,c,d,e} 当二进制00000就代表什么都不取, 10000代表取a,01000代表取b,11000代 表取a,b如此 所以我们需要枚举的数量就是00000到11111,也就是0到1<<n位,<<代表左移操作 */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int main() { int i,j,N,ans=0,M,sum=0,temp=0; int arr[100]={0}; cin >>N>>M; for(i=1;i<=N;i++) { arr[i] = i; } for(i=1;i<=N;i++) { sum+=arr[i]; } if((sum%2==0&&M%2!=0) || (sum%2!=0&&M%2==0)) { cout <<0<<endl; return 0; } temp = (sum-M)/2; for(i=1;i<(1<<N);i++) //将所有可能性一一枚举。 { sum = 0; //这一步很重要。每次清零 for(j=0;j<N;j++) { if(i&(1<<j)) //如果括号里为真值(不为0)即从数组选取一定数量的数相加;可以将所有情况列举; sum += arr[j+1]; if(sum>temp) break; } if(sum == temp) ans++; } cout<<ans<<endl; return 0; }