第六周:数组 + 递归 + 函数

本文列举了一系列编程题目,涉及汉诺塔、阿克曼函数、回文数检测、素数因子、分数序列求和、星期计算、特殊求和、杨辉三角形和整数数组比较。每个题目提供了详细的描述、输入输出格式及样例,并给出了相应的解决方案代码,旨在锻炼和提升读者的算法思维和递归编程能力。
摘要由CSDN通过智能技术生成

1.汉诺塔

题目:

汉诺塔问题是指:一块板上有三根针 A、B、C。A 针上套有 64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 B 针上,每次只能移动一个圆盘,移动过程可以借助 C 针。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。从键盘输入需移动的圆盘个数,给出移动的过程。

对于汉诺塔问题,当只移动一个圆盘时,直接将圆盘从 A 针移动到 B 针。若移动的圆盘为 n(n>1),则分成几步走:
1、把 (n-1) 个圆盘从 A 针移动到 C 针(借助 B 针);
2、A 针上的最后一个圆盘移动到 B 针;
3、C 针上的 (n-1) 个圆盘移动到 B 针(借助 A 针)。

每做一遍,移动的圆盘少一个,逐次递减,最后当 n 为 1 时,完成整个移动过程。
因此,解决汉诺塔问题可设计一个递归函数,利用递归实现圆盘的整个移动过程,问题的解决过程是对实际操作的模拟。

函数设计如下:
void Hanoi(int n, char a, char b, char c);
void Move(int n, char a, char b);
请注意定义全局变量记录移动次数。

【样例输入】

3

【样例输出】

1: Move 1 from A to B
2: Move 2 from A to C
3: Move 1 from B to C
4: Move 3 from A to B
5: Move 1 from C to A
6: Move 2 from C to B
7: Move 1 from A to B

代码:

#include <iostream>
using namespace std;

//函数功能:将n个盘从a借助c挪到b;
int i = 0;
void Move(int n, char a, char b)
{
    i ++;
    cout << i << ": Move " << n << " from " << a << " to " << b << endl;
}
void Hanoi(int n, char a, char b, char c)
{
    if(n == 1)
    {
        Move(n, a, b);

    }
    else
    {
        Hanoi(n - 1, a, c, b);
        Move(n, a, b);
        Hanoi(n - 1, c, b, a);
    }
}
int main()
{
    int n;
    char a, b, c;
    a = 'A';
    b = 'B';
    c = 'C';
    cin >> n;
    Hanoi(n, a, b, c);
    return 0;
}

2.阿克曼

题目:

编程计算Ackermann阿克曼函数的值,定义一个int Ack(int m, int n)的递归函数,在主函数中输入m和n,调用该递归函数返回其值。Ack(m,n)的定义如下(m≥0,n≥0):

Ack(0,n) = n+1

Ack(m,0) = Ack(m-1,1)

Ack(m,n) = Ack(m-1,Ack(m,n-1)) (m>0, n>0)

同时,请打印出计算Ackermann函数时所需的递归调用次数。

【输入形式】m和n
【输出形式】函数结果和递归调用次数。
【样例输入】2 3
【样例输出】

9
nAckNum=44

代码:

#include <iostream>
using namespace std;

int k = 0;
int Ack(int m, int n)
{
    k ++;
    if(m < 0 || n < 0) return -1;
    if(m == 0) return n + 1;
    if(n == 0) return Ack(m - 1, 1);
    if(m != 0 && n != 0) return Ack(m - 1, Ack(m, n - 1));
    return 0;
}

int main()
{
    int m, n;
    int result;
    cin >> m >> n;
    result = Ack(m, n);
    if(result == -1) return 0;
    else
    {
        cout << result << endl;
        cout << "nAckNum=" << k;
    }
    return 0;
}

3.回文数

题目:

所谓回文数是指具有如下性质的整数:一个整数,当它的各位数字逆序排列,形成的整数与原整数相同,这样的数称为回文数。例如,素数11是回文数,373也是回文数,因为其各位数字对换位置后仍然为11、373。编写函数int Loop(int x),判断一个整数x是否为回文数,如果x是回文数则返回1(或者true),否则返回0(或者false)。编写程序,接收控制台输入的两个整数a,b。调用Loop函数输出a到b之间(包括a和b)的所有为偶数的回文数。
【输入形式】控制台输入两个整数a和b(必有a<b),以空格分隔。
【输出形式】输出有若干行,每行有一个a和b之间的回文数。输出各行上的数字不重复,且从小至大依次按序输出。
【样例输入】3 120
【样例输出】
4
6
8
22
44
66
88
【样例说明】输入整数a=3,b=120,要求输出所有[3, 120]之间的为偶数的回文数。按升序分行输出所有符合题意的整数。

代码:

#include <iostream>
using namespace std;

int Loop(int x)
{
    int sum = 0, n = x;
    while(n > 0)
    {
        sum = sum * 10 + n % 10;
        n = n / 10;
    }
    if(x == sum) return 1;
    else return 0;
}

int main()
{
    int a, b, i, n;
    do{
        cin >> a >> b;
    }while(a >= b);
    
    for(i = a; i <= b; i ++)
    {
        n = Loop(i);
        if(i % 2 == 0 && n == 1)
            cout << i << endl;
    }
    return 0;
}

4.为素数的因数

题目:

请编写一个函数,完成以下计算:在主函数中接受输入整数n(n>0),调用函数计算并输出n的所有为素数的正因数,若没有则在返回主函数以后输出No Answer。

【输入形式】从控制台输入整数n。

【输出形式】按照从小到大的顺序,在一行上输出n的所有为素数的正因数,各个正因数之间用一个空格分隔,若没有则输出No Answer。

【样例输入】36

【样例输出】2 3

【样例输入】1

【样例输出】No Answer

【样例说明】输入的整数N为36,36的所有正因数为1、2、3、4、6、9、12、18、36,其中只有2和3为素数,所以输出2 3。

【样例说明】如果测试数据是11,则输出11。注意本身也是因子的素数。

代码:

#include <iostream>
using namespace std;

int prime(int x)
{
    for(int i = 2; i < x; i ++) if(x % i == 0) return 0;
    return 1;
}

void func(int n)
{
    int flag = 0;
    for(int i = 2; i <= n; i ++)
    {
        if(n % i == 0)
        {
            if(prime(i) == 1)
            cout << i << " ";
            flag = 1;
        }
    }
    if(flag == 0) cout << "No Answer";
}

int main()
{
    int n;
    cin >> n;
    func(n);
}

5.分数序列和

题目:

编写函数double FUN(double n)计算以下分数序列的前n项之和,其中参数n由主函数输入,FUN函数的返回值在主函数中输出。

2/1,3/2,5/3,8/5,13/8,21/13,…

【输入形式】正整数n

【输出形式】分数序列的和(浮点数,精确到小数点后4位)

【样例输入】99

【样例输出】160.4849

【提示】因为运行时间的限制,请不要使用递归函数。注意int类型存储越界的问题。

代码:

#include <iostream>
#include <iomanip>

using namespace std;

double FUN(double n){
    double a = 2.0;
    double b = 1.0;
    double r = 0.0;
    for(int i = 1; i <= n; i++)
    {
        r += (a / b);
        double temp = a;
        a += b;
        b = temp;
    }
    return r;
}
int main(){
    int n;
    double r;
    cin >> n;
    r = FUN(n);
    cout << fixed << setprecision(4) << r;
    return 0;
}

6.星期几

题目:

编写一个原型为bool LeapYear(int year)的函数判断某年是否为闰年。

编写一个原型为int GetDays(int year, int month, int day)的函数,计算从公元1年1月1日到该日期第year年month 月day日的天数。

通过对年的循环,依次累加求和即可:sum+=365 or 366。另外:主函数要求输入年月日,并计算出当天是XINGQI几。其中1、2、…、6、7依次输出为XINGQI 1、XINGQI 2、…、XINGQI 6、XINGQI 7。

bool LeapYear(int year);

int GetDays(int year, int month, int day);

【输入形式】**year month day

【输出形式】**XINGQI 1、XINGQI 2……XINGQI 6、XINGQI 7中的一个,拼音和数字之间有一个空格

【样例输入】2011 11 3

【样例输出】XINGQI 4

代码:

#include <iostream>
#include <iomanip>

using namespace std;

bool LeapYear(int year){
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ) return true;
    else return false;
}

int GetDays(int year, int month, int day){
    int t = 0;
    for(int i = 1; i < year; i ++)
    {
        if(LeapYear(i)) t += 366;
        if(!LeapYear(i)) t += 365;
    }
    for(int i = 1; i < month; i ++)
    {
        switch(i){
            case 1 : t += 31; break;
            case 3 : t += 31; break;
            case 5 : t += 31; break;
            case 7 : t += 31; break;
            case 8 : t += 31; break;
            case 10 : t += 31; break;
            case 12 : t += 31; break;
            case 4 : t += 30; break;
            case 6 : t += 30; break;
            case 9 : t += 30; break;
            case 11 : t += 30; break;
            case 2:
                if(LeapYear(i)) t += 29;
                if(!LeapYear(i)) t += 28;
        }
    }
    t += day;
    return t;
}

int main(){
    int n, y, r, t;
    cin >> n >> y >> r;
    t = GetDays(n, y, r);
    cout << "XINGQI " << (t % 7);
    return 0;
}

7.特殊求和

题目:

编写函数int fun(int a,int n)求Sn = a + aa + aaa + … + aa…a 的值(最后一个数中 a 的个数为 n ),其中 a 是一个1~9的数字,例如:

2 + 22 + 222 + 2222 + 22222 (此时 a=2 n=5 ) 。参数由主函数传入,最终结果传回主函数再输出。

【输入形式】一行,包括两个整数,第一个为a,第2个为n(1 ≤ a, n ≤ 9),以空格分隔。

【输出形式】一行,Sn的值。

【样例输入】2 5

【样例输出】24690

代码:

#include <iostream>
#include <iomanip>
using namespace std;

int fun(int a, int n){
    int s = a;
    for(int i = 2; i <= n; i ++)
    {
        a = a * 10 + a;
        s += a;
    }
    return s;
}

int main(){
    int a, n;
    cin >> a >> n;
    cout << fun(a, n);
    return 0;
}

8.杨辉三角形

题目:

请编写函数求解实现用一维或二维数组存储杨辉三角形,并编写函数实现在屏幕上显示如下杨辉三角形:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

【输入形式】

从键盘输入整数n(n>=0且n<=12)
【输出形式】
在屏幕上输出n+1行杨辉三角形。

【输入样例1】
3
【输出样例1】
1
1 1
1 2 1
1 3 3 1

代码:

#include <iostream>
#include <iomanip>
using namespace std;

void Yanghui(int n){
    int s[20][20];
    for(int i = 0; i <= n; i ++)
    {
        s[i][0] = 1;
        s[i][i] = 1;
    }
    for(int i = 2; i <= n; i ++)
    {
        for(int j = 1; j < i; j ++)
        {
            s[i][j] = s[i - 1][j - 1] + s[i - 1][j];
        }
    }
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < 2 * (n - i); j ++) cout << " ";
        for(int k = 0; k <= i; k ++){
            cout << setw(4) << s[i][k];
        }
        cout << endl;
    }
}

int main(){
    int n;
    do{
        cin >> n;
    }while(n < 0 || n > 12);
    Yanghui(n);
    return 0;
}

9.比较两组整数

题目:

编写一个函数实现数组元素的录入,编写第二个函数实现数组元素的输出,编写第三个函数实现以下功能:比较两组整数是否有相同的元素,并打印输出这些相同的元素,不考虑元素的顺序,并忽略元素重复的情况,每组元素个数不超过100。例如:
2 5 10 17 10 8 5 10 12
与下列一组整数:
12 8 10 17 5 2
相同。

若需要其他函数请自行设计,原则是主函数尽量短小、清晰,代码整体可读性强。
【输入形式】
首先输入第一组整数的个数,再输入第一组整数,以空格分割;然后输入第二组整数的个数,再输入第二组整数,以空格分割。
【输出形式】
打印两组整数中相同的元素,顺序以第一组的整数输入顺序为准,如果没有相同元素,打印“No Answer”
【输入样例1】

9
2 5 10 17 10 8 5 10 12

6
12 8 10 17 5 2
【输出样例1】

"#"代表空格
2#5#10#17#8#12#
【样例1说明】
输入两组整数
2 5 10 17 10 8 5 10 12
12 8 10 17 5 2
由于这两个数组具有相同的元素,顺序打印第一行与第二行相同的元素

【样例输入2】

7
3 4 7 8 1 22 3
6
1 9 43 5 6 78

【样例输出2】

1

代码:

#include <iostream>
#define N 100
using namespace std;

int flag =0;

void Input(int s[], int num)
{
    for(int i = 0; i < num; i ++)
    {
        cin >> s[i];
    }
}

void Sort(int a[], int b[], int as, int bs)
{
    for(int i = 0; i < as; i ++)
    {
        for(int j = 0; j < bs; j ++)
        {
            if(a[i] == b[j])
            {
                cout << b[j] << ' ';
                flag = 1;
                b[j] = -1;
            }
        }
    }
    if(!flag) cout << "NO ANSWER";
}

int main()
{
    int anum;
    cin >> anum;
    int a[N];
    Input(a, anum);
    int bnum;
    cin >> bnum;
    int b[N];
    Input(b, bnum);
    Sort(a, b, anum, bnum);
    return 0;
}

欢迎提问,学弟学妹们加油~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只可爱的小猴子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值