6-1 求阶乘(递归版)
double Fac(int x)
{
//出口
if(x == 0)
return 1;
//小的
return x*Fac(x-1);
}
6-5 递归实现指数函数
//求x的n次幂函数
double calc_pow( double x, int n )
{
//出口是幂次为零
if(n == 0)
return 1;
//分级为更小的步骤
else
return calc_pow(x, n-1)*x;
}
6-7 递归实现顺序输出整数
本题要求实现一个函数,对一个整数进行按位顺序输出。
函数接口定义:
void printdigits( int n );
函数printdigits
应将n
的每一位数字从高位到低位顺序打印出来,每位数字占一行。
裁判测试程序样例:
#include <stdio.h>
void printdigits( int n );
int main()
{
int n;
scanf("%d", &n);
printdigits(n); return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
12345
输出样例:
1
2
3
4
5
答案:
void printdigits( int n )
{
//出口为个位数时
if(n < 10)
{
printf("%d\n", n);
return;
}
//因为要逆序输出,所以要先递归调用,然后再打印
printdigits(n/10);
printf("%d\n",n%10);
}
6-8 递归求简单交错幂级数的部分和
本题要求实现一个函数,计算下列简单交错幂级数的部分和:
f(x,n)=x−x2+x3−x4+⋯+(−1)n−1xn
函数接口定义:
double fn( double x, int n );
其中题目保证传入的n
是正整数,并且输入输出都在双精度范围内。函数fn
应返回上述级数的部分和。建议尝试用递归实现。
裁判测试程序样例:
#include <stdio.h>
double fn( double x, int n );
int main()
{
double x;
int n;
scanf("%lf %d", &x, &n);
printf("%.2f\n", fn(x,n));
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
0.5 12
输出样例:
0.33
答案:
double fn( double x, int n ){
//
if(n==1)
return x;
else
return x-x*(fn(x,n-1));
}
6-9 递归求逆序数
本题要求实现一个求非负整数的逆序数的简单函数,建议用递归实现。
函数接口定义:
unsigned int reverse( unsigned int number );
其中 number
是用户传入的参数, number
的值不超过unsigned int
的范围;函数须返回用户传入的非负整数number
的逆序数,建议用递归实现。
裁判测试程序样例:
#include <stdio.h>
# include <math.h>
unsigned int reverse( unsigned int number );
int main()
{
unsigned int n;
scanf("%u", &n);
printf("%u\n", reverse(n));
return 0;
}
/* 请在这里填写答案 */
输入样例:
12340
输出样例:
4321
答案:
unsigned int reverse( unsigned int number )
{
int m = 0; //用来计算当前number有多少位
unsigned int num = number;
while(num)
{
num/=10;
m++;
}
//递归出口,如果num处理到个位数,返回
if(number < 10)
return number;
//分解为,每个个位数,乘以当前数的位数 + 分解为计算当前数除以十的小部分
return (number%10)*pow(10, m-1) + reverse(number/10);
}
6-10 青蛙跳台阶
一只青蛙一次可以跳上1级台阶、2级台阶、3级台阶。求这只青蛙跳上一个n(0<=n<=20)级台阶总共有多少种跳法(先后次序不同算不同的结果)。
函数接口定义:
int climb ( int n );
n为台阶数,函数须返回 n级台阶的跳法总数。
裁判测试程序样例:
#include <stdio.h>
int climb(int n);
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", climb(n));
return 0;
}
/* 请在这里填写答案 */
输入样例:
5
输出样例:
13
答案:
int climb ( int n )
{
//出口有仨,分别为差三步、两步、一步到达终点,0为特例
//差一步只有一种方式、差两步只有两种方式、差三步只有四种方式。
if(n == 0)
return 1;
if(n == 1)
{
return 1;
}
if(n == 2)
{
return 2;
}
if(n == 3)
{
return 4;
}
//分解为更小的:
return climb(n-1) + climb(n-2) + climb(n-3);
}
6-11 回文
回文是前后两个方向拼写完全相同的字符串。回文的例子如“radar”、"able was i ere i saw elba"和"ABCBA","ABBA"。很显然,空字符串是回文,任何一个只有1个字符的字符串是回文。编写一个函数 testPalindrome, 判断一个字符串是否是回文。
函数接口定义:
在这里描述函数接口。例如: int testPalindrome ( char *start, char *end);
其中 start
和 end
都是用户传入的参数。 字符指针start
指向字符串第一个字符,字符指针end
指向字符串最后一个字符('\0'
前的一个字符)。
裁判测试程序样例:
#include <stdio.h>
#include <string.h>
int isPalindrome(char *str);
int testPalindrome(char *start, char *end);
int main(void)
{
char s[30];
gets(s);
if (isPalindrome(s))
{
printf("%s is a palindrome.\n", s);
}
else
{
printf("%s is not a palindrome.\n", s);
}
return 0;
}
//isPalindrome函数用来调用testPalindrome
//该函数为用户提供了更友好的接口
//我们可以称isPalindrome函数是testPalindrome函数的包装函数
int isPalindrome(char *str)
{
return testPalindrome(str, str + strlen(str) - 1);
}
/* 请在这里填写答案 */
输入样例1:
radar
输出样例1:
radar is a palindrome.
输入样例2:
ABBA
输出样例2:
ABBA is a palindrome.
输入样例3:
ABCA
输出样例3:
ABCA is not a palindrome.
答案:
int testPalindrome ( char *start, char *end)
{
//出口1:start >= end 时,说明检查到最后也符合回文的条件
if(start >= end)
return 1;
//出口2:*start != *end时,说明不是回文数
if(*start != *end)
return 0;
//就将回文数缩小为更小的回文数。
return testPalindrome((start+1), (end-1));
}
7-2 二分查找(折半查找)
描述
已知一个有n个元素的从小到大排列的整数序列,序列中的数据没有重复。现在要查找一个给定的值key,输出key在此序列中出现的位置。
例如:在序列[1,2,3,5,8,9,12,21,37,49,55,613]中,查找5的结果是4,表示找到了,位置是4(第4个数).
输入
第一行包含一个正整数k,表示有k组测试数据。1 <= k <= 100。接下来是k组数据。
对于每组数据,首先包含一行两个整数,n和key,表示该组数据整数序列的元素个数n和要查找的值key。(1 <=n<=1000)
然后的一行中包含n个从小到大排列好的整数,依次给出序列的每个元素,相邻两个整数之间用空格隔开。
题目中所有元素和key的绝对值不超过10000。
输出
对于每组数据,若序列中存在key,输出key第一次出现的位置;否则输出-1。
每个输出单独占一行。
样例输入
3
5 3
2 3 5 6 7
4 5
1 2 3 4
1 1
1
样例输出
2
-1
1
答案:
#include <stdio.h>
#include <string.h>
int ErFen(int left, int right, int a[], int key);
int main(void)
{
int k;
//组数
scanf("%d", &k);
for(int j = 0; j < k; j++)
{
int n;
int key;
//输入数组长度
scanf("%d %d", &n, &key);
int a[n];
//输入数组
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
//递归算法
printf("%d\n",ErFen(0, n, a, key));
}
}
//递归二分查找
int ErFen(int left, int right, int a[], int key)
{
int mid = (left+right)/2;
//找到或left>right为出口
if(left > right)
return -1;
//找到了返回
if(a[mid] == key)
{
return mid+1;
}
if(a[mid] > key)
{
return ErFen(left,mid-1,a,key);
}
if(a[mid] < key)
{
return ErFen(mid+1,right,a,key);
}
}