[递归专题打卡]2021 6.30-7.2
作者:互联网
同步于本人CSDN https://blog.csdn.net/qq_39391544
2021/6/30
链接:https://ac.nowcoder.com/acm/problem/14310
来源:牛客网
★字符串逆序
输入一个字符串,长度在100以内,按相反次序输出其中的所有字符。
输入描述:
输入一个字符串
输出描述:
输出反序的字符串
示例1
输入
tsinghua
输出
auhgnist
解答:
1 #include<stdio.h> 2 #include<string.h> 3 int lenth; 4 void Output(char* a,int n) 5 { 6 if(n==lenth) 7 return; 8 Output(a,n+1); 9 printf("%c",a[n]); 10 } 11 int main() 12 { 13 char a[101]; 14 scanf("%s",a); 15 lenth=strlen(a); 16 Output(a,0); 17 return 0; 18 }
链接:https://ac.nowcoder.com/acm/problem/14320
来源:牛客网
★杨辉三角
杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数。
它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加。
下面给出了杨辉三角形的前4行:
1
1 1
1 2 1
1 3 3 1
给出n,输出它的前n行。
输入描述:
输入包含一个数n。
输出描述:
输出杨辉三角形的前n行。每一行从这一行的第一个数开始依次输出,中间使用一个空格分隔。请不要在前面和后面输出多余的空格。
示例1
输入
4
输出
1 1 1 1 2 1 1 3 3 1
说明
1 <= n <= 34。
解答:
1 #include<iostream> 2 #define Maxn 100000 3 using namespace std; 4 5 int N; 6 int a[Maxn]; 7 void Output(int n) 8 { 9 if(n==N+1) 10 return ; 11 a[n]=1; 12 // for(int j=2;j<n;j++){ 13 // a[j]=a[j-1]+a[j]; 14 // }//与倒序循环有微妙差距 15 for(int j=n-1;j>=2;j--){ 16 a[j]=a[j-1]+a[j]; 17 } 18 for(int j=1;j<=n;j++){ 19 if(j==1){ 20 cout<<a[j]; 21 }else{ 22 cout<<' '<<a[j]; 23 } 24 } 25 cout<<endl; 26 Output(n+1); 27 } 28 int main() 29 { 30 a[1]=1; 31 cin>>N; 32 Output(1); 33 return 0; 34 }
链接:https://ac.nowcoder.com/acm/problem/14356
来源:牛客网
★s01串
s01串初始为"0"
按以下方式变换
0变1,1变01输入描述:
1个整数(0~19)
输出描述:
n次变换后s01串
示例1
输入
3
输出
101
说明
初始为0 第一次变化后为 1 第二次变化后为 01 第三次变化后为 101
备注:
数据规模和约定 0~19
解答:
1 #include<iostream> 2 using namespace std; 3 4 string Output(int n) 5 { 6 if(n==0) return "0"; 7 if(n==1) return "1"; 8 return Output(n-2)+Output(n-1); 9 } 10 int main() 11 { 12 int N; 13 cin>>N; 14 cout<<Output(N); 15 return 0; 16 }
2021/7/1
链接:https://ac.nowcoder.com/acm/problem/14703
来源:牛客网
★★素数回文
现在给出一个素数,这个素数满足两点:
1、 只由1-9组成,并且每个数只出现一次,如13,23,1289。
2、 位数从高到低为递减或递增,如2459,87631。
请你判断一下,这个素数的回文数是否为素数(13的回文数是131,127的回文数是12721)。
输入描述:
输入只有1行。
第1行输入一个整数t,保证t为素数。
数据保证:9<t<109
输出描述:
输出一行字符串,如果t的回文数仍是素数,则输出“prime”,否则输出"noprime"。
示例1
输入
13
输出
prime
说明
13的回文数是131,131是素数
示例2
输入
17
输出
noprime
说明
17的回文数是171,171不是素数(因子有3)
备注:
素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。 素数的回文数为题意中的定义,1331不是素数的回文数。
解答:
#include<iostream> using namespace std; bool Isprime(long long number) { if(number<2) return false; for(int i=2; i<=number/i; i++) { if(number%i==0) return false; } return true; } int main() { char num[10]; long long a,b,c; cin>>a; for(c=a/10; c!=0; c/=10) { a*=10; a+=c%10; } if(Isprime(a)) cout<<"prime"; else cout<<"noprime"; return 0; }
链接:https://ac.nowcoder.com/acm/problem/14582
来源:牛客网
★★★LP钱不够吃货LP参加了珠海美食节,每见一家摊位都会大吃一顿,但是如果不加收敛,接下来的日子就只能吃土了,所以,他决定只向前,不回头,花最少的钱,在美食节上吃出一条血路。在美食节的矩形地图中,LP站在左上角的入口,请帮助Ta到达右下角的出口。
输入描述:
第一行包含一个正整数T(T<=10),表示有T组测试数据。 每组数据第一行包含一个正整数n(3 <= n<=20)。 给定一个n*n矩阵图,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是花费和,返回所有路径中最小的花费和。 无摊位时花费为0,不会有负花费。
输出描述:
对于每一组数据,有一行输出,返回最小花费,最后输出无换行。
示例1
输入
1 5 25 81 51 98 43 19 10 36 81 91 95 38 7 84 40 87 27 72 9 30 33 81 68 21 71
输出
270
解答:
#include<iostream> using namespace std; int main() { int num[21][21]={0}; int N,x; cin>>N; while(N--){ cin>>x; for(int i=1; i<=x; i++) { for(int j=1; j<=x; j++) cin>>num[i][j]; } for(int m=x;m>=1;){ for(int n=x-1;m>=1;){ for(int i=m,j=n;i>=m,j<=m;i--,j++){ //cout<<"("<<i<<','<<j<<") "; if(i==x){ num[i][j]+=num[i][j+1]; }else if(j==x){ num[i][j]+=num[i+1][j]; }else{ num[i][j]+=min(num[i+1][j],num[i][j+1]);//保证每一个子问题的最优解 } } //cout<<"("<<m<<','<<n<<") "; if(n==1){ m--; }else{ n--; } } } cout<<num[1][1]<<endl; } return 0; }
这是一道数塔问题的变种,核心思想是相同的,即运用动态规划的思想,把一个复杂的问题划分成无数个子问题,保证每一个子问题的最优解,通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决.得到全局最优解
此题比起简单的数塔,难在DP的顺序,例如下图矩阵大小为4*4时:
而每一层的起始点循环的方向则是按照红线的顺序(不唯一)
补充:
数塔
在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
已经告诉你了,这是个DP的题目,你能AC吗?
Input
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
Output
对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。
Sample Input
1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Sample Output
30
#include<iostream> #include<cstdio> using namespace std; int N; int a[10000],book[10000]; void dfs(int step) { if(step==N+1) { for(int i=1; i<=N; i++) { printf("%5d",a[i]); //cout<<a[i]<<' '; } cout<<endl; return ; } for(int i=1; i<=N; i++) { if(book[i]==0) { a[step]=i; book[i]=1; dfs(step+1); book[i]=0; } } return ; } int main() { cin>>N; for(int i=1;i<=N;i++) { a[i]=i; book[i]=0; } dfs(1); return 0; }
链接:https://ac.nowcoder.com/acm/problem/14839
来源:牛客网
★最大公约数
输入两个数,求最大公约数。
输入描述:
输入两个数a,b.
输出描述:
输出a和b的最大公约数
示例1
输入
6 3
输出
3
解答:
#include<iostream> using namespace std; int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b); } int main() { int a,b; cin>>a>>b; cout<<gcd(a,b); return 0; }
2021/7/2
链接:https://ac.nowcoder.com/acm/problem/14359
来源:牛客网
★Fibonacci数列
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
输入描述:
输入包含一个整数n。
输出描述:
输出一行,包含一个整数,表示Fn除以10007的余数。
示例1
输入
10
输出
55
示例2
输入
22
输出
7704
备注:
说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。
数据规模与约定
1 <= n <= 1,000,000。
解答:
#include<iostream> using namespace std; int main() { int n; int num[3]={1,1,0}; cin>>n; if(n==1||n==2){ cout<<"1"; }else{ for(int i=3; i<=n; i++) { num[2]=(num[0]+num[1])%10007; num[0]=num[1]; num[1]=num[2]; } cout<<num[2]; } return 0; }
1.全排列
题目描述
输出自然数 1 到 n 所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 n。
输出格式
由 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 5 个场宽。
输入输出样例
输入
3
输出
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
说明/提示
1≤n≤9
解答:
#include<iostream> #include<cstdio> using namespace std; int N; int a[10000],book[10000]; void dfs(int step) { if(step==N+1) { for(int i=1; i<=N; i++) { printf("%5d",a[i]); //cout<<a[i]<<' '; } cout<<endl; return ; } for(int i=1; i<=N; i++) { if(book[i]==0) { a[step]=i; book[i]=1; dfs(step+1); book[i]=0; } } return ; } int main() { cin>>N; for(int i=1;i<=N;i++) { a[i]=i; book[i]=0; } dfs(1); return 0; }
模板:
void dfs(int step)
{
判断边界{
...// 输出
返回
}
尝试每一种可能{
判断状态{
...
继续下一步 dfs(step+1)
...//初始化执行这一步前所改变的状态
}
}
返回
}
2.所有组合
题目描述
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出rr个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你输出所有组合。
例如n=5,r=3,所有组合为:
12 3 , 1 2 4 , 1 2 5 , 1 3 4 ,1 3 5 , 1 4 5 , 2 3 4 , 2 3 5 , 2 4 5 , 3 4 5
输入格式
一行两个自然数n,r(1<n<21,0≤r≤n)。
输出格式
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
注意输出时,每个数字需3个场宽,pascal可以这样:
write(ans:3);
输入输出样例
输入
5 3
输出
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
解答:
#include<iostream> #include<cstdio> using namespace std; int n,r; int a[10000]; void dfs(int m) { if(a[0]==r) { for(int i=1; i<=r; i++) { printf("%3d",a[i]); //cout<<a[i]<<' '; } cout<<endl; return ; } for(int i=m; i<=n; i++) { a[++a[0]]=i; dfs(i+1); a[a[0]--]=0; } } int main() { cin>>n>>r; dfs(1); return 0; }
标签:输出,return,int,7.2,6.30,Output,打卡,include,输入 来源: https://www.cnblogs.com/Knight02/p/14965724.html