洛谷NOIP2002 普及组 选数 +NOIP1999普及组 回文数

两道日常的练习题,废话不多说,直接上题上代码:

这道题目的难点在于怎样去根据一个不同的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;   
}

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

残念亦需沉淀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值