竞赛入门(a+b, 密码破译,母牛的故事)

1.输入两个整数a和b,计算a+b的和

本题很简单,但是注意此题是多组测试数据,即需要不停的接收系统的测试输入,你都可以计算结果并输出

样例输入:

1 1
10 20

样例输出:

2
30

错误示例:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	int a, b, c, d;
	scanf("%d %d", &a, &b);
	scanf("%d %d", &c, &d);
	printf("%d\n%d", a + b, c + d);
	return 0;
}

 初看并看不出有什么大深奥,极大可能写出上面的代码,但是并没有通过测试,原因是并不满足多组测试,它上面的代码只能满足两组数据的相加,所有我们思考该如何改进,使其可以进行多组测试。

改进版1:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	int a, b;
	while (scanf("%d %d", &a, &b) == 2) {
		printf("%d\n",a + b);
	}
	return 0;
}

改进版2: 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	int a, b;
	while (scanf("%d %d", &a, &b)) {
		printf("%d\n",a + b);
	}
	return 0;
}

为了使其可以进行多组测试,我们加入了一个循环,循环的作用是在确定scanf的内容是整数时继续经行运算,从而可以做到将两个数相加。 

注解:

(scanf("%d %d", &a, &b) == 2 这行代码的意思是当你输入的是两个整型因为它的返回值是2于==2符合,所以循环继续;

scanf("%d %d", &a, &b)的意思是当检查到这两个正整数时,循环继续,这两个式子在这里效果一样。

 2.要将"China"译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母.
例如,字母"A"后面第4个字母是"E"."E"代替"A"。因此,"China"应译为"Glmre"。
请编一程序,用赋初值的方法使cl、c2、c3、c4、c5五个变量的值分别为,’C’、’h’、’i’、’n’、’a’,经过运算,使c1、c2、c3、c4、c5分别变为’G’、’l’、’m’、’r’、’e’,并输出。

 样例输入:

China

样例输出:

Glmre

 解答:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	char ch1, ch2, ch3, ch4, ch5;
	scanf("%c%c%c%c%c", &ch1,&ch2,&ch3,&ch4,&ch5);
	printf("%c%c%c%c%c", ch1 + 4, ch2 + 4, ch3 + 4, ch4 + 4, ch5 + 4 );
	return 0;
}

 主要涉及字符的运算,只要能想到使用字符,和字符加减法,这题还是比较轻松解决的。

 重点(母牛的故事)

 

3

有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?

样例输入:

2
4
5
0

样例输出:

2
4
6

采用迭代解法(运行的时间长)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int countCows(int n) {
    if (n <= 0) {
        return 0;
    }
    else if (n <= 3) {
        return n;
    }
    else {
        return countCows(n - 1) + countCows(n - 3);
    }
}

int main() {
    int n;
    int years[1000];  // 假设最多输入1000年的年份
    int count = 0;

    scanf("%d", &n);

    // 读取输入年份
    while (n != 0) {
        years[count] = n;
        count++;
        scanf("%d", &n);
    }

    // 计算并输出每年的母牛数量
    for (int i = 0; i < count; i++) {
        int totalCows = countCows(years[i]);
        printf("%d\n", totalCows);
    }

    return 0;
}

注解:首先我解题,探究母牛的数量,列出以下图表:

年数:                      牛数:

  1.                                 1
  2.                                 2
  3.                                 3 
  4.                                 4
  5.                                 5  
  6.                                 9      
  7.                                13              

我们探索发现规律:

当x>4时:

f(x)=f(x-1)+f(x-3)

根据这个式子,我们决定用递归解决问题

首先建立递归的函数:

int countcow(int i){

if(i<=0){
return 0;
}
else if(i<4){
return i;
}
else{
return countcow(i-1)+countcow(i-3)
}
}

这段函数可以充分演绎

f(x)=f(x-1)+f(x-3)这个方程

接下来我们考虑输出格式的问题:

它的输出格式式连续的,且要求在输入0的时候显示输出;所以我们考虑使用while循环加上数组实现解答;

尤其注意,此时我们将数组的内的值变成count

而count=0;

而在每一次我们输入一次数组时,count++

这是老程序员的经验,希望读者能吸收

有一个小注意:这里的year[]数组保证了正确的输出,它和变量n是绑定的

采用递归+动态规划解法(运行时间较短)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int countCows(int n) {
    int dp[1001];  
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;

    for (int i = 4; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 3];
    }

    return dp[n];
}

int main() {
    int n;
    int years[1000]; 
    int count = 0;

    scanf("%d", &n);

    
    while (n != 0) {
        years[count] = n;
        count++;
        scanf("%d", &n);
    }

    
    for (int i = 0; i < count; i++) {
        int totalCows = countCows(years[i]);
        printf("%d\n", totalCows);
    }

    return 0;
}

注解:它减少了运算次数,首先自定义了dp[0],dp[1],dp[2],dp[3],然后通过for循环找出所有的值

 补充知识:

  1. 迭代:

    • 迭代是通过循环结构来重复执行某段代码,直到满足特定条件为止。
    • 迭代使用显式的控制结构(例如for循环、while循环)来控制代码的执行流程。
    • 迭代通常需要维护一个迭代变量或指针,并在每次迭代中更新其值。
    • 迭代更加直观和易于理解,适用于问题具有可重复性质的情况。
  2. 递归:

    • 递归是指在函数内部调用自身的过程。
    • 递归通过将原问题分解为规模更小的子问题来解决,直到达到基本情况(递归终止条件)。
    • 递归使用隐式的系统栈来保存每一层递归调用的信息,以便在递归结束后能够返回到正确的位置。
    • 递归需要注意递归终止条件的正确性,否则可能导致无限递归和栈溢出等问题。

迭代和递归各有优缺点,应根据问题的特性和实际需求选择合适的方法。一般来说,迭代通常更直观且效率较高,而递归则更能简化问题的表达和理解,但可能会带来额外的时间和空间开销。

需要注意的是,在某些情况下,迭代和递归可以相互转换,并且有时候使用递归可以更简洁地表达问题的解决思路。但在实际应用中,我们应当根据问题的具体要求和性能需求来选择合适的方法。

 

  • 21
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码一探索者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值