洛谷打卡Day04–函数调用与递归
P1028-- 数的计算
题目描述
我们要求找出具有下列性质数的个数(包含输入的自然数nn):
先输入一个自然数nn(n \le 1000n≤1000),然后对此自然数按照如下方法进行处理:
不作任何处理;
在它的左边加上一个自然数,但该自然数不能超过原数的一半;
加上数后,继续按此规则进行处理,直到不能再加自然数为止.
输入输出格式
输入格式:
11个自然数nn(n \le 1000n≤1000)
输出格式:
11个整数,表示具有该性质数的个数。
输入输出样
输入格式:
6
输出格式:
6
原理解释:
满足条件的数为
6,16,26,126,36,136
解题思路
不说多了,直接开始:
我们以4为例子来进行说明
4后面可以跟上1,2组成14,24
14后面跟不了,24可以跟上1组成124
再加上4本身就可以得到4的种类
即 14,24,124,4
而我们只要算出1,2的种类就可以加起来得到4的种类
**因此,我们得到
f[1]=1
f[2]=2=f[1]+1
f[3]=2=f[1]+1
f[4]=4=f[1]+f[2]+1
f[5]=4=f[1]+f[2]+1
源代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n;
int f[1001];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i/2;j++){
f[i]+=f[j];
}
f[i]++;
}
cout<<f[n];
return 0;
}
递推和递归的区别
参考大佬的博客,自己对于递归和递推的区别刚开始也不清楚,但是本题由于找的数学规律,是递推的用法两者区别:https://www.cnblogs.com/jycboy/p/5304347.html
P1036 选数
题目描述
已知 n个整数 x1,x2,…,xn,以及1个整数k(k<n)。从n个整数中任选k个整数相加,可分别得到一系列的和。例如当n=4,k=3,n=4,k=3,4个整数分别为3,7,12,193,7,12,19时,可得全部的组合与它们的和为:
3+7+12=223+7+12=22
3+7+19=293+7+19=29
7+12+19=387+12+19=38
3+12+19=343+12+19=34。
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=293+7+19=29。
输入输出格式
输入格式:
键盘输入,格式为:
n,kn,k(1 \le n \le 20,k<n1≤n≤20,k<n)
x1, x2,…,xn )x (1≤xi ≤5000000)
输出格式:
屏幕输出,格式为: 11个整数(满足条件的种数)。
输入输出样例
输入格式:
4 3
3 7 12 19
输出格式:
1
解题思路
调用DFS函数,找到三个数后,调用判断是否是质数的函数,如果满足条件,则将方案数加1,找到一种方案时,回溯到上一次的结点,从那个结点开始进入到最深处。这里的dfs需要入口地址。
源代码
#include<iostream>
using namespace std;
bool isprime(int a){
for(int i=2;i*i<a;i++){
if(a%i==0)
return false;
}
return true;
}
int n,k;
int a[24];
bool visit[24];
long long count=0;
void DFS(int m,int sum,int begin){
if(m==k){
if(isprime(sum))
count++;
else
return ;
}
else{
for(int i=begin;i<n;i++){
if(visit[i])
continue;//如果是已经访问过该结点,则继续向下访问
else
visit[i]=true;//如果没有访问,修改访问状态
DFS(m+1,sum+a[i],i+1);//找到一个结点后,继续调用深搜,找下一个满足条件的结点
visit[i]=false; //回溯,将找过的上一个结点状态设置为初始化状态。每次回溯时返回上一次的结点。
}
}
return ;
}
int main(){
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>a[i];
}
DFS(0,0,0);
cout<<count;
return 0;
}
DFS思想
深度优先搜索用一个数组存放产生的所有状态。
(1) 把初始状态放入数组中,设为当前状态;
(2) 扩展当前的状态,产生一个新的状态放入数组中,同时把新产生的状态设为当前状态;
(3) 判断当前状态是否和前面的重复,如果重复则回到上一个状态,产生它的另一状态;
(4) 判断当前状态是否为目标状态,如果是目标,则找到一个解答,结束算法。
(5) 如果数组为空,说明无解。
参考链接:https://baike.baidu.com/item/深度优先搜索/5224976
判断素数的方法,除了上面比较常见的求依次整除的方式,还有其他方法,例如
https://blog.csdn.net/qq_41754350/article/details/81609688
https://blog.csdn.net/HZEUHJEJNJ/article/details/78658865