洛谷P1618 三连击(升级版) (详细注释 + C++)

题目描述

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

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

输入格式

三个数,A,B,C.

输出格式

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

输入输出样例

输入 #1复制

1 2 3

输出 #1复制

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

说明/提示

保证 A<B<C

//本题是P1008的升级版,原题是1:2:3,本题只是更改了比例而已,解题思路相同,只需要稍加改动即可,原题的题解详见https://blog.csdn.net/qq_45472866/article/details/104090334(详细注释+ 2种方法)

#include<iostream>
#include<algorithm>
using namespace std;

int sum(int x);
int fact(int x);              
int gcd(int x,  int y)   //求x,y的最大公约数(辗转相除法),详见https://blog.csdn.net/qq_45472866/article/details/104059702

int main() {
    int a, b, c, cnt;
    cin >> a >> b >> c;
    int k = gcd(gcd(a, b), c);
    a /= k;  b /= k;  c /= k;            //本行和上行有没有都可,但题目中没有说明a、b、c互质,如果给出的数据不互质就可能溢出
    int x, y, z, max;
    cnt = 0;
    max = 999 * a / c;         //得到a的最大值,以免多做无用功
    for (x = 123; x <= max; x++) {     //其他和P1008的题解一样,在此不再重复说明
        if(x % a == 0){
            y = x * b / a;     //突然发现上面那两行真没必要,如果先除以a再乘以b就不会溢出了,哈哈(有点尴尬啊!)
            z = x * c / a;
            if (sum(x) + sum(y) + sum(z) == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 && fact(x) * fact(y) * fact(z) == 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9) {
                cout << x  << " "<< y << " " << z << endl;
                cnt++;
            }
        }
    }

    if (!cnt)
        cout << "No!!!";

    return 0;
}

int sum(int x) {
    return x % 10 + (x / 10) % 10 + x / 100;
}
int fact(int x) {
    return (x % 10) * ((x / 10) % 10) * (x / 100);
}

int gcd(int x, int y) {
    int r = x % y;
    if (!r)
        return y;
    return gcd(y, r);
}
发布了48 篇原创文章 · 获赞 47 · 访问量 3386

猜你喜欢

转载自blog.csdn.net/qq_45472866/article/details/104090326