题目描述
输入输出样例1:
输出样例1:
输入样例2:
输出样例2:
代码如下(以下代码为统计有多少种不同的k个数相加,当然,其中有多种相加的结果都是同一个素数):
//P1036 选数
//已知 n 个整数 x1,x2,…,xn,以及1个整数k(k<n)。从n个整数中任选k个整数相加,可分别得到一系列的和。例如当n=4,k=3,4个整数分别为3,7,12,19时,可得全部的组合与它们的和为:
//3+7+12=22
//3+7+19=29
//7+12+19=38
//3+12+19=34。
//现在,要求你计算出和为素数共有多少种。
//例如上例,只有一种的和为素数:3+7+19=29。
#include<iostream>
using namespace std;
int a[21]; //记录原始的n个数
int k; //记录要挑选的数字个数
int sum=0; //记录k个数相加的和,初始为0
int n; //原始数据有n个
int num[21];
int result[100000];
int count=0;
//记录每种的结果数字,因为20个数据,最大的可能性就是取10个相加。结果的可能性为71060,
//所以定义一个100000的数组,能够保存所有结果。
int result_number=1;
//判断数字n是否为素数
bool sushu(int n){
bool flag=true;
if(n==1) return false;
if(n==2||n==3) return true;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
flag=false;
}
return flag;
}
//xuanshu(int star,int m)函数,表示,从原数组a[21]中下标为start位置,再取m个数相加。
void xuanshu(int start,int m){
//从a[21]的下标i开始,逐个尝试
for(int i=start;i<=n-m+1;i++)
{
if(m==1)
//递归的边界
//m=1,说明已经选择到最后一个数字了
//判断原来k-1个数的和+现在k的值,是否是质数,如果是,count加1
{
num[m]=a[i];
sum=0;
for(int j=1;j<=k;j++)
sum+=num[j];
//sum为k个数相加的和
//如果sum为素数
if(sushu(sum))
{
count++;
//int flag2=1;
//flag2标记,1表示原来所有的结果中,不存在当前的结果数字
//for(int t=0;t<result_number;t++)
// if(result[t]==sum) flag2=0;
//flag=0,表示这个结果出现过了
//flag2标记,1表示原来所有的结果中,不存在当前的结果数字 ,将当前的结果保存到数组result中,
//result_number表示这是第几个不同的结果数字。
//if(flag2)
//{
//result[result_number]=sum;
//result_number++;
//}
//输出加法式子
//for(int j=k;j>1;j--)
//cout<<num[j]<<"+";
//cout<<num[1]<<"="<<sum<<endl;
}
}
else //如果m不等于1,说明数字m个数字没取完
{
num[m]=a[i];
//将当前的a[i]的值保存到num数组中,num数组中保存要相加的数字。
xuanshu(i+1,m-1);
//接着下标变为当前位置的下一个位置,再取m-1个数字。
}
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int l=1;l<=100000;l++)
result[l]=1;
//初始化保存不同结果的数组,因为结果都是素数,不可能为1
xuanshu(1,k);
//从第一个位置开始选择k个数字相加
//cout<<"结果为素数的有:"<<endl;
//for(int j=1;j<=result_number-1;j++)
//cout<<result[j]<<endl;
//cout<<"共有"<<result_number-1<<"个"<<endl;
//cout<<result_number-1<<endl;
cout<<count-1<<endl;
}
如果题目稍加变化,要统计相加得到的素数结果,有多少个不同的素数,
代码如下(以下代码能统计结果为不同的素数个数):
//P1036 选数
//已知 n 个整数 x1,x2,…,xn,以及1个整数k(k<n)。从n个整数中任选k个整数相加,可分别得到一系列的和。例如当n=4,k=3,4个整数分别为3,7,12,19时,可得全部的组合与它们的和为:
//3+7+12=22
//3+7+19=29
//7+12+19=38
//3+12+19=343。
//现在,要求你计算出和为素数共有多少种。
//例如上例,只有一种的和为素数:3+7+19=29。
#include<iostream>
using namespace std;
int a[21]; //记录原始的n个数
int k; //记录要挑选的数字个数
int sum=0; //记录k个数相加的和,初始为0
int n; //原始数据有n个
int num[21];
int result[100000];
//记录每种的结果数字,因为20个数据,最大的可能性就是取10个相加。结果的可能性为71060,
//所以定义一个100000的数组,能够保存所有结果。
int result_number=1;
//判断数字n是否为素数
bool sushu(int n){
bool flag=true;
if(n==1) return false;
if(n==2||n==3) return true;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
flag=false;
}
return flag;
}
//xuanshu(int star,int m)函数,表示,从原数组a[21]中下标为start位置,再取m个数相加。
void xuanshu(int start,int m){
//从a[21]的下标i开始,逐个尝试
for(int i=start;i<=n-m+1;i++)
{
if(m==1)
//递归的边界
//m=1,说明已经选择到最后一个数字了
//判断原来k-1个数的和+现在k的值,是否是质数,如果是,count加1
{
num[m]=a[i];
sum=0;
for(int j=1;j<=k;j++)
sum+=num[j];
//sum为k个数相加的和
//如果sum为素数
if(sushu(sum))
{
int flag2=1;
//flag2标记,1表示原来所有的结果中,不存在当前的结果数字
for(int t=0;t<result_number;t++)
if(result[t]==sum) flag2=0;
//flag=0,表示这个结果出现过了
//flag2标记,1表示原来所有的结果中,不存在当前的结果数字 ,将当前的结果保存到数组result中,
//result_number表示这是第几个不同的结果数字。
if(flag2)
{
result[result_number]=sum;
result_number++;
}
//输出加法式子
//for(int j=k;j>1;j--)
//cout<<num[j]<<"+";
//cout<<num[1]<<"="<<sum<<endl;
}
}
else //如果m不等于1,说明数字m个数字没取完
{
num[m]=a[i];
//将当前的a[i]的值保存到num数组中,num数组中保存要相加的数字。
xuanshu(i+1,m-1);
//接着下标变为当前位置的下一个位置,再取m-1个数字。
}
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int l=1;l<=100000;l++)
result[l]=1;
//初始化保存不同结果的数组,因为结果都是素数,不可能为1
xuanshu(1,k);
//从第一个位置开始选择k个数字相加
//cout<<"结果为素数的有:"<<endl;
//for(int j=1;j<=result_number-1;j++)
//cout<<result[j]<<endl;
//cout<<"共有"<<result_number-1<<"个"<<endl;
cout<<result_number-1<<endl;
}