洛谷:P1618 三连击(升级版)

三连击(升级版)

题目描述

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 AA<B<C


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

思路:

题目会给出A,B,C,要输出所有比例符合A:B:C的数,要求按第一个数字升序排序。因为已经固定要在9个位置填上数字,所以我们可以使用dfs对9个位置进行搜索。因为每个数字只能使用一次,所以已经已经用过的数字就标记一下,当搜索次数大于9的时候就进行判断,算出三个数字A,B,C,看看两两数字之间的比例是否是正确的,注意要使用乘法,不然的话会出现除情况相等但实际不相等的情况,然后直接输出即可,因为搜索本来就是升序的,这样即可AC。

代码:

#include 
using namespace std;
int a,b,c,flag=-1;
vector<int> ans(10);
vector<bool> book(10,false);
void dfs(int x){
	if(x>9){
		int A,B,C;
		A=ans[1]*100+ans[2]*10+ans[3];
		B=ans[4]*100+ans[5]*10+ans[6];
		C=ans[7]*100+ans[8]*10+ans[9];
		if(A>=B||A>=C||B>=C){
			return;
		}else{
			if(A*c==C*a&&A*b==B*a){//不能用除,因为为int,用除可能出错,直接两个数直接比值的互乘
				flag=1;
				cout << A << ' ' << B << ' ' << C << '\n';//因为搜索输出是升序的,直接输出即可
			}
		}
		return;
	}
	for(int i=1;i<=9;i++){
		if(!book[i]){
			book[i]=true;
			ans[x]=i;
			dfs(x+1);
			book[i]=false;
		}
	}
}
int main() {
	cin >> a >> b >> c;
	dfs(1);
	if(flag==-1){
		cout << "No!!!";
	}
}

你可能感兴趣的:(算法,dfs)