首页 > 其他分享 >C语言——习题练习(一)

C语言——习题练习(一)

时间:2024-12-03 23:28:07浏览次数:15  
标签:ba 组合 int 练习 C语言 CSDN 习题 取值

习题:

        现在有两种面值的邮票,一种为8角,一种为6角。你要付n角的邮资(不能多付也不能少付),请给出邮票张数最少的方案。如果没有正好的方案则输出-1。

输入格式:

        只有一行,为若干个整数(至少有两个)。这些整数最后一个整数一定是-1(输入结束标志,无需处理),其他整数均大于0,这些大于0的整数代表邮资。

输出格式:

        若干行,每行依次对应输入的一个邮资,如果该邮资有正好的方案,则为两个用空格分隔的整数,代表张数最少的方案。前边的数字代表需要的8角的邮票的张数,后边的数字代表6角的邮票的张数;如果该邮资没有正好的方案则输出-1。测试用例保证所有整数均可以用int存储。。

输入样例:

24 14 11 -1

输出样例:

3 0
1 1
-1

代码1如下:

#include <stdio.h>
int main()
{
	int n = 0;
	int x, y;
	while (1)
	{
		again:
		scanf("%d", &n);
		if (n != -1)
		{
			for (x = 0; x <=n/6; x++)
			{
				for (y = 0; y <=n/8; y++)
				{
					if ((6*x + 8*y) == n)
					{
						printf("%d %d\n", y, x);
						goto again;
					}
				}
			}
            printf("-1\n");
		}
		else
		{
			break;
		}
	}
	return 0;
}

运行结果如下:

代码2如下:

#include <stdio.h>
int ba;
int main() {
	int n;
	while (1) {
		scanf("%d", &n);
		if (n == -1)break;
		ba = n / 8;
		int tt = 1;
		while (ba >= 0) {
			if ((n - ba * 8) % 6 == 0) {
				printf("%d %d\n", ba, (n - ba * 8) / 6);
				tt = 2;
				break;
			}
			ba -= 1;
		}
		if (tt == 1)printf("-1\n");
	}
}

运行结果如下:

下面进行代码解读:

代码1:

        x代表6角面值,y代表8角面值,n代表总面值,在外层循环中,循环变量x的取值范围是从0n/6,内层循环中循环变量y的取值范围是从0n/8。这种按照从小到大的顺序去遍历所有可能的xy的取值组合,本质上是一种穷举的方式。由于循环是从最小的可能值(也就是0)开始逐步增加,当第一次找到满足6*x + 8*y == n条件的xy时,它们在当前的穷举顺序下就是使得x + y相对最小的组合。

        举例来说,如果n = 24,外层循环x会先取0,然后内层循环y0开始取值,当y = 3(此时8 * 3 = 24 ,x还是0)时就满足条件了,因为循环从最小开始尝试,所以优先找到的就是数之和相对最小的组合(这里x + y = 0 + 3 = 3),不会出现先找到其他更大和的组合情况,比如x = 46 * 4 = 24,此时y = 0x + y = 4 )这种相对和更大的情况会在满足条件的更小组合之后才会去尝试到(但因为已经找到组合并输出了,后续更大和的情况就不会再去管了)。

        因此应该在x循环下遍历y才能保证最小。

代码2:
  1. 外层循环对 bay 的取值调整)的控制:代码中首先计算 ba = n / 8,这里是确定了 y(也就是对应 8 的倍数的数量)的初始最大可能值。然后进入 while (ba >= 0) 循环,这个循环会从这个最大可能值开始,逐步递减 ba(也就是 y 的取值逐步减少)。这种从大到小尝试 y 的取值方式是关键所在。因为在尝试用 6 和 8 的倍数组合去凑 n 的过程中,优先考虑让较大的数(这里是 8)尽可能多地参与,这样得到的组合中两个数的和相对会更小。例如,如果 n = 24,一开始 ba = 24 / 8 = 3,此时会先检查 3 个 8 能否满足情况,发现满足(因为 24 - 3 * 8 = 00 能被 6 整除),那就直接找到了 y = 3x = 0 的组合(x + y = 3),这就是数之和最小的组合。如果不先从大的 y 值开始尝试,可能会先找到其他 xy 值更大的组合来凑 n,比如先从 y = 0 开始尝试,然后不断增加 x 去凑,可能就会先找到 x = 4y = 0 这样 x + y = 4 的相对更大的组合了。        
  2. 内层条件判断对 x(n - ba * 8) % 6 == 0 部分)的确定:在每次 bay 的取值)确定后,通过 (n - ba * 8) % 6 == 0 这个条件来判断,剩余的数(也就是 n 减去当前 y 个 8 之后剩下的部分)能否被 6 整除。如果能整除,那就意味着找到了满足 6 * x + 8 * y = n 的 x(即 (n - ba * 8) / 6)和 y(即 ba)的一组值。  而且由于外层循环是从大到小递减 y 的取值,一旦找到满足条件的组合,就是按照这种有利于数之和最小的顺序下最先出现的组合,后续即使继续递减 y 再找,得到的组合中两数之和也只会更大(因为优先是让较大数 8 尽可能多地参与凑数了),所以此时找到的组合就是 x + y 最小的组合。

本期练习讲解就到这里~~~

往期回顾:

C语言——指针初阶(三)-CSDN博客

C语言——指针初阶(二)-CSDN博客

C语言——海龟作图(对之前所有内容复习)_c语言画图小动物代码-CSDN博客

C语言——指针初阶(一)-CSDN博客

C语言函数递归经典题型——汉诺塔问题_汉诺(hanoi)塔问题-CSDN博客

C语言——数组基本知识(二)_c语言四维数组的使用方法-CSDN博客

C语言——数组基本知识(一)-CSDN博客

C语言——数组逐元素操作练习-CSDN博客

C语言编程练习:验证哥德巴赫猜想 进制转换 rand函数-CSDN博客

标签:ba,组合,int,练习,C语言,CSDN,习题,取值
From: https://blog.csdn.net/hjx1235/article/details/144226175

相关文章

  • C语言数组作业
    作业1:使用二维数组输出杨辉三角作业2:通过键盘输入6名学生的成绩,输出6名学生的成绩,使用冒泡法对班级学生的成绩升序排序,输出排序后成绩作业3:有如下两个数组:intarr[]={1,2,3,4,5,6,7,8,9,0};intbrr[]={3,7,15,9,20,2,100,4};要求,自定义一个数组crr,将上面两个数组......
  • c语言顺序结构,算法,输出与输入
    ......
  • C语言打印杨辉三角
    由杨辉三角可知,最左边与最右边都为一因此先把他们赋值为1,for(i=0;i<n;i++) { arr[i][0]=1; for(j=0;j<n;j++) { if(i==j) arr[i][j]=1; } }通过上述图发现,从n=3开始,出现除1以外的数字; 因此可对他们进行赋值if(i>=2&&j>=1) { arr[i][j]=arr[i-1......
  • 【C语言篇】C 语言贪吃蛇:指尖上的贪吃冒险,代码编织的娱乐狂欢
    我的个人主页我的专栏:C语言,希望能帮助到大家!!!点赞❤收藏❤一、引言贪吃蛇游戏作为一款具有悠久历史且广为人知的电子游戏,始终在编程学习与实践领域占据着独特的地位。其简洁的规则与丰富的可玩性,使其成为众多编程初学者迈向游戏开发世界的理想入门项目,同时也为经验丰......
  • 初识C语言学习笔记
    ......
  • C语言易错、常用知识集锦(持续更新ing 欢迎来看&评论呀)
     引言 本文主要是用于初学者写题时经常遇到的模型题块,看完此篇文章可快速、全面掌握常用常见题型。 里面的易错点,是从周围同学和自己亲身犯过的错误以及遗忘点,还是很适合初学者们(其实我和我同学也算是初学者的但是此篇文章由欧阳佳老师亲自审核通过的!!大家放心学习呀!!)一......
  • [题目记录]一本通高手练习-软件开发
    题意有两个软件需要开发,每个软件分为\(m\)部分,把这总共\(2m\)个任务分配给\(n\)个人,每个人完成软件1,软件2的一部分所消耗的时间分别为\(a_i,b_i\),这\(n\)个人同时工作,完成的时间就是这\(n\)个人最慢的一个人完成他的所有任务的时间.通过分配任务......
  • 如何在C语言中制作一个计算器
    喜大普奔啊,100粉丝了,上次说的计算器来喽^V^主播一点没鸽(哇,这也太高产了吧),感谢大家的陪伴立一个flag,1000粉丝的时候制作一个图画送给大家^V^正文:简易计算机要求1、打印欢迎界面。2、提醒用户输入参与运算的两个数字,以及运算符号,根据运算符号输出结果。3、询问用户是否继......
  • C语言实验 循环结构2
    时间:2024.12.3一、实验7-1求符合给定条件的整数集#include<stdio.h>intmain(){inta,b,s,g;scanf("%d",&a);inth=0;for(inti=a;i<=a+3;i++){for(intj=a;j<=a+3;j++){for(intk=a;k<=a+3;k++){if((i!=j)&&(i!......
  • C语言实验 一维数组
    时间:2024.12.3一、实验7-1交换最小值和最大值#include<stdio.h>intmain(){intn,a[10],i,min=0,max=0;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&a[i]);}for(i=0;i<n;i......