两道日常的练习题,废话不多说,直接上题上代码:
这道题目的难点在于怎样去根据一个不同的k值,通过代码来实现将所有符合题目要求的数字相加并且不重复的功能。下面请看代码,会有详细的讲解:
#include<iostream>
using namespace std;
int n,k;
const int N=1e2+10;
int a[N];
bool pd(int x){//质数的判断函数
if(x==1) return false;//其实这里也不用特判1 但是因为题目说n可能为1 还是考虑一下
//我也挺纳闷如果n为1的话 那么k<n应该是怎么回事
if(x==2) return true;
for(int i=2;i*i<=x;i++)
if(x%i==0) return false;
return true;
}
int ans;//最后输出的
void dfs(int cnt,int sum,int startx){
/*
代码的精华部分,用来计算所有不同情况的数字相加并进行ans的更新
*/
if(cnt==k){//当此时sum中包含的加数个数达到k的时候
if(pd(sum))//判断此时的sum是否符合质数条件
++ans;
return;
}
for(int i=startx;i<=n;i++){//这里的startx是搜索过程中 当前的sum即将加的值
dfs(cnt+1,sum+a[i],i+1);//将cnt值 也就是加数的个数加1 同时sum加上对应下标的数字
//并且将i加上1以便于计算从i+1所对应下标值相加的情况
}
return ;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
dfs(0,0,1);//分别代表加数个数 加数的和 以及每次搜索中下一个加的数字下标
cout<<ans<<endl;
return 0;
}
这道题目如果实在不能一次性看懂可以用测试的样例来根据代码进行模拟,有助于更好的理解代码。
接下来看第二道题目:
代码如下:
#include<cstdio>//
#include<cstring>//会用到strlen函数计算l
const int S=150;//因为一开始M最多有100位 每次add最多加一位 所以其实最多为130位,这里设置的大
int step,N,M,l;
char c[S],d[S];
bool pd(char c[]){
for(int i=0;i<l;i++)
if(c[i]!=c[l-i-1])
return false;
return true;
}
void add(char c[]){
for(int i=0;i<l;i++){
d[i]=c[l-1-i];
}
l+=2;//由于相加可能会进位使l的长度变大,所以这里将l增加2
for(int i=0;i<l;i++){
c[i]+=d[i];
if(c[i]>=N){
c[i]-=N;
++c[i+1];
}
}
while(!c[l-1]) l--;//如果l设置长了把他减回去
}
int main(){
scanf("%d%s",&N,c);
l=strlen(c);
for(int i=0;i<l;i++){
if(c[i]>='0' && c[i]<='9') c[i]-='0';
else c[i]=c[i]-'A'+10;//将字符作处理以便于像整数那样加减
}
while(!pd(c)){
++step;
if(step>30) break;
add(c);
}
if(step<=30) printf("STEP=%d\n",step);
else printf("Impossible!\n");
return 0;
}