【暴力枚举】三连击(升级)

[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-99GIsgkO-1673455313422)(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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值