三连击以及三连击(升级)

文章讲述了NOIP1998普及组的一道编程题目,要求将1到9的数字分成3组,组成3个三位数,比例为1:2:3。解决方案包括枚举数字并进行数位拆分,检查每个数的每一位是否不同,以及它们的和与积是否等于预期值。文章还提供了代码示例,并提到了问题的升级版,即给定比例A:B:C,寻找满足条件的三位数组合,且考虑了数据的特殊性如整除和数位不重复的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[NOIP1998 普及组] 三连击

题目背景

本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。

题目描述

1 , 2 , … , 9 1, 2, \ldots , 9 1,2,,9 9 9 9 个数分成 3 3 3,分别组成 3 3 3 个三位数,且使这 3 3 3 个三位数构成 1 : 2 : 3 1 : 2 : 3 1:2:3 的比例,试求出所有满足条件 3 3 3 个三位数。

输入格式

输出格式

若干行,每行 3 3 3 个数字。按照每行第 1 1 1 个数字升序排列。

样例 #1

样例输入 #1

样例输出 #1

192 384 576
* * *
...

* * *
(剩余部分不予展示)
思路:枚举以及数位拆分

1.变量:数字,从小到大枚举

2.数的范围是:三位数的范围是100-999,要形成1:2:3的比例那么第一个数的范围不能超过333,并且三个数的每位数都不相等(看了好几遍题目配合样例看才看懂,容易忽略:9个数不重复的组成三个三位数的数,要求输出所有的可能方案))

表示三位数的方法:ijk 则有a=i*100+j *10+ k *1;则有b=2a ,c=3a,分解i j k(数位拆分) ,因为三个数的每位数都不相等 , 对a,b,c三个数的所有数位进行求和、求积,看是否等于1-9的和、积

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WS5XSz63-1673543102158)(C:\Users\23711\AppData\Roaming\Typora\typora-user-images\image-20230111222312606.png)]

//利用数学思维:两个集合的元素分别求和、求积都相等,那么两个集合相等
//第一个集合是组成的三个数,第二个集合是1-9
#include <stdio.h>
int main()
{
	int a,b,c;
	int k,j;
	for(a=123;a<333;a++){//第一个数的范围
		b=2*a;
		c=3*a;
		//数位拆分求和、求积,判断三个数的每位数是否有重复
		k=a/100+a/10%10+a%10+b/100+b/10%10+b%10+c/100+c/10%10+c%10;
		j=(a/100)*(a/10%10)*(a%10)*(b/100)*(b/10%10)*(b%10)*(c/100)*(c/10%10)*(c%10);
		if(k==(1+2+3+4+5+6+7+8+9) && j==(1*2*3*4*5*6*7*8*9)){
			printf("%d %d %d\n",a,b,c);
		}
	}
	return 0;
}
//拆分求和:a/100(百位)+a/10%10(十位)+a%10(个位);

三连击(升级版)

题目描述

1 , 2 , … , 9 1, 2,\ldots, 9 1,2,,9 9 9 9 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A : B : C A:B:C A:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!

//感谢黄小U饮品完善题意

输入格式

三个数, A , B , C A,B,C A,B,C

输出格式

若干行,每行 3 3 3 个数字。按照每行第一个数字升序排列。

样例 #1

样例输入 #1

1 2 3

样例输出 #1

192 384 576
219 438 657
273 546 819
327 654 981

提示

保证 A < B < C A<B<C A<B<C


upd 2022.8.3 \text{upd 2022.8.3} upd 2022.8.3:新增加二组 Hack 数据。

60分

//思路:先判断第一个数是否能够被A整除,满足比例,如果可以就按比例输出第二个 第三个数
//然后进行数位拆分判断是否三个数的数位不重复
//如果数据满足条件则计数,如果cnt=0,则输出no
#include <stdio.h>
int main()
{
	int a,b,c;
	int cnt=0;
	scanf("%d %d %d",&a,&b,&c);
	for(int i=123;i<333;i++){
		if(i%a==0){//整除:余数为0
			int j=i/a*b;//按比例计算
			int k=i/a*c;
			int n=i/100+i/10%10+i%10+j/100+j/10%10+j%10+k/100+k/10%10+k%10;
			int m=(i/100)*(i/10%10)*(i%10)*(j/100)*(j/10%10)*(j%10)*(k/100)*(k/10%10)*(k%10);
			if(n==(1+2+3+4+5+6+7+8+9) && m==(1*2*3*4*5*6*7*8*9)){
				cnt++;
				printf("%d %d %d\n",i,j,k);
			}
		}
	}
	if(cnt==0){
		printf("No!!!\n");
	}
	return 0;
}

全部AC代码

没有能全部AC是因为:没有判断abc是否为0的特殊情况+!用了中文

#include <stdio.h>
int main()
{
	int a,b,c;
	int cnt=0;
	scanf("%d %d %d",&a,&b,&c);
	if(a==0||b==0||c==0||(c>333&&c<400)){//判断是否为0(很容易忽略!!!)
	    printf("No!!!\n");
	    return 0;
	}
	for(int i=123;i<333;i++){
		if(i%a==0){//整除:余数为0
			int j=i/a*b;//按比例计算
			int k=i/a*c;
            //数位拆分
			int n=i/100+i/10%10+i%10+j/100+j/10%10+j%10+k/100+k/10%10+k%10;
			int m=(i/100)*(i/10%10)*(i%10)*(j/100)*(j/10%10)*(j%10)*(k/100)*(k/10%10)*(k%10);
            //判断是否重复、全部出现123456789
			if(n==(1+2+3+4+5+6+7+8+9) && m==(1*2*3*4*5*6*7*8*9)){
				cnt++;//计数满足条件的
				printf("%d %d %d\n",i,j,k);
			}
		}
	}
	if(cnt==0){
		printf("No!!!\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值