做的第一道涉及算法的题
题目:
已知 n 个整数 x1,x2,…,xn,以及一个整数 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)。
分析
- 使用深度优先算法,从四个数中选出三个数
- 判断是否是素数
统计数量,输出
坑爹之处
- 输入 3 2 1 1 1 居然结果是3 ! 明明是三个一样的素数好吗!!
- 允许上面那种重复,居然不允许a+b b+a这样的重复
- 写到这里我突然发现我是个智障
- 我要回去重学语文了。。
- QAQ
我的代码:
#include<iostream>
using namespace std;
int n,k,book[20],a[20],y=1,sushu[20];
int num[20],total=0,sum=0;
int is_prime(int shuzi){
int sign=0;
for(int i=2;i<shuzi;i++){
if(shuzi %i ==0) sign=1;
}
if(sign==0) return 1;
else return 0;
}
int dfs( int step){
if(step==k+1){
for(int i=1;i<=k;i++){
sum+=num[a[i]];
}
if(is_prime(sum) ){
total++;
}
sum=0;
return 0;
}
for(int i=1;i<=n;i++){
if(book[i]==0){
a[step]=i;
book[i]=1;
dfs(step+1);
book[i]=0;
}
}
return 0;
}
int jiecheng(int num1){
int sum=1;
for(int i=1;i<=num1;i++){
sum=sum*i;
}
return sum;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>num[i];
}
dfs(1);
total=total/(jiecheng(k));
cout<<total<<endl;
}
总结:
- 不熟练dfs,所以采用了先按123……列出排列顺序,再对应到相应的数组,多用了很多数组。。
- 最后去重时候, 最开始只考虑了的题中所给输入输出 4选3 时,重复六次,但这个数字并不适用于其他情况。
- 先插一个别人家的代码。。。↓↓↓
#include<cstdio>
int n,k,ans;
int a[22];
int is_prime(int n){
if(n == 1 || n == 0)return 0;
if(n == 2)return 1;
for(int i = 2; i*i <= n; i++)
if(n % i == 0)return 0;
return 1;
}
void dfs(int pos,int pps,int sum){
if(!pos) { ans +=is_prime(sum);return ;}
for(pps; pps <= n; pps++)dfs(pos -1,pps +1, sum + a[pps]);
}
int main(){
scanf("%d%d", &n,&k);
for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
dfs(k,1, 0);
printf("%d\n", ans);
return 0;
}
- 首先,在判断素数时候,只需要计算到根号n即可。否则时间复杂度是指数倍。
- 写法太简略,差评!
- 在dfs中,第一位从1开始循环,第二位从2开始循环,第三位从3开始循环……可以省出无数代码量!
- 太困了 睡觉! 2017年5月7日02:23:33