P1618 三连击(升级版)

三连击(升级版)

题目描述

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

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

输入格式

三个数,A,B,C

输出格式

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

样例 #1

样例输入 #1

1 2 3

样例输出 #1

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

提示

保证 A<B<C


upd 2022.8.3:新增加二组 Hack 数据。

2.题解

2.1 set集合去重 + 字符化处理

思路

这里采用三重循环枚举第一个数,后面的两个数根据比例即可算出
最重要的是如何检验后面算出的两个数和第一个数这三个数没有重复的数字!!!

代码

#include<bits/stdc++.h>
using namespace std;
bool hasDuplicateDigits(int num1, int num2, int num3){
	set<char> charSet;
	string combined = to_string(num1) + to_string(num2) + to_string(num3);
    for (char ch : combined) {
        charSet.insert(ch);
    }
	return charSet.size() == combined.length() && charSet.find('0') == charSet.end(); // 防止其中混入 0 
}

int main(){
	int A, B, C, count = 0;
	cin >> A >> B >> C;
	// 任何一个为 0 时,均不可能存在 
	if (A == 0 || B == 0 || C == 0) {
		cout << "No!!!";
		return 0;
	}
	for(int i = 1; i <= 9; i++){
		for(int j = 1; j <= 9; j++){
			for(int k = 1; k <= 9; k++){
				if(i != j && j != k){
					int fn = i * 100 + j * 10 + k;
					int sn = fn * B / A;
					int tn = fn * C / A;
					if(hasDuplicateDigits(fn, sn, tn)){
						count++;
						cout << fn << ' ' << sn << ' ' << tn << endl;
					}
				}
			}
		}
	}
	if(count == 0) cout << "No!!!";
} 

2.2 排列枚举

思路:使用next_permutation函数

next_permutation函数可以将数组从当前字节序不断向字节序更大的方向排列,next_permutation 函数会返回一个布尔值,表示是否存在下一个排列
若字节序达到最大会返回一个false,其余情况返回true。
类似从[1,2,3] -> [1,3,2] -> [2,1,3] -> [2,3,1] -> [3,1,2] -> [3,2,1]

代码

要注意的一个地方是,我预留了a数组的第一位不做处理,所以后面我在调用next_permutation的时候,起点位置必须是a.begin() + 1 而不是 a.begin()
同时注意结尾位置是a.end(),是数组最后一个元素的后面一个,而不是最后一个元素!!!

#include<bits/stdc++.h>
using namespace std;
int main(){
	int A, B, C, count = 0;
	cin >> A >> B >> C;
	vector<int> a(10);
	for(int i = 1; i <= 9; i++){
		a[i] = i;
	} 
	do{
		int fn = a[1] * 100 + a[2] * 10 + a[3];
		int sn = a[4] * 100 + a[5] * 10 + a[6];
		int tn = a[7] * 100 + a[8] * 10 + a[9];
		if(fn * B == sn * A && fn * C == tn * A){
			cout << fn << ' ' << sn << ' ' << tn << endl;
			count++;
		}
	}while(next_permutation(a.begin() + 1, a.end()));
	if(!count) cout << "No!!!";
}
posted @   DawnTraveler  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示