洛谷 P1008 [NOIP1998 普及组] 三连击

本文详细解析了如何通过暴力枚举和布尔值表来解决一道编程竞赛题目,涉及C++和Python代码示例。

​本​文​由​J​z​w​a​l​l​i​s​e​r​原​创​,​发​布​在​C​S​D​N​平​台​上​,​遵​循​CC 4.0 BY-SA协​议​。​
​因​此​,​若​需​转​载​/​引​用​本​文​,​请​注​明​作​者​并​附​原​文​链​接​。​
​违​者​必​究​,​谢​谢​配​合​。​
​个​人​主​页​:​blog.csdn.net/jzwalliser

​题​目​

洛​谷​ ​P1008 [NOIP1998 普及组] 三连击

​[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
* * *
...

* * *
(剩余部分不予展示)

想法

首先,题目主要的意思是:找到三个三位数,分别为 n n n 2 n 2n 2n 3 n 3n 3n,而且这三个三位数包含 1 1 1~ 9 9 9的所有数字。
那么,立即可以想到一种暴力枚举的方法:将 100 100 100~ 999 999 999所有数字枚举一遍。那么,对于数字 n n n来说,只需要试 100 100 100~ 333 333 333即可(因为 3 n ≤ 999 3n\leq 999 3n999)。

实现

  1. 建立一个布尔值的对照表,出现的数字标记为 1 1 1,没有出现的数字标记为 0 0 0
  2. 枚举 1 1 1~ 333 333 333,并把出现的数字标记下来。
  3. 每次枚举后,都检查:是否出现啦 1 1 1~ 9 9 9所有数字,若有则输出,没有则继续枚举。

题解

C++

#include<iostream>
using namespace std;
bool num[12]; //建立布尔值表
void sep(int n){ //该函数用于拆分数字
    for(int i = 0;i < 3;i++){
        num[n % 10] = 1;
        n /= 10;
    }
}

bool check(){ //该函数用于检查是否出现1~9所有数字
    for(int i = 1;i <= 9;i++){
	    if(num[i] == 0){
	        return 0;
	    }
    }
    return 1;
}

void init(){ //初始化列表
    for(int i = 1;i <= 9;i++){
	    num[i] = 0;
    }
}

int main(){
	for(int i = 100;i < 333;i++){
	    int a = i * 2;
	    int b = i * 3;
	    sep(i); //拆分数字
	    sep(a); //拆分数字
	    sep(b); //拆分数字
	    if(check()){
	        cout << i << " " << a << " " << b << "\n";
	    }
	    init(); //初始化列表
	}
	return 0;
}

Python

num = [0,0,0,0,0,0,0,0,0,0] #建立布尔值表
def sep(n): #该函数用于拆分数字
	global num
	for i in range(3):
		num[int(n % 10)] = 1
		n = (n - n % 10) / 10
		
def check(): #该函数用于检查是否出现1~9所有数字
	global num
	for i in range(1,10):
		if num[i] == 0:
			return 0
	return 1

def init(): #初始化列表
	global num
	num = [0,0,0,0,0,0,0,0,0,0]

for i in range(100,334):
	sep(i) #拆分数字
	sep(i * 2) #拆分数字
	sep(i * 3) #拆分数字
	if check():
		print(i,i * 2,i * 3)
	init()

难度

难度:★☆☆☆☆
这道题并不是很难,只要稍动脑筋就可以想出来。主要考察暴力枚举算法,以及如何拆分数字:先模 10 10 10,再除以 10 10 10

结尾

还有别的思路吗?欢迎评论区留言哦!记得关注我啊(˃ ⌑ ˂ഃ ),​我​们​下​期​再​见​!​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值