洛谷 P1618. 三连击 --dfs和next_permutation函数两种方法

三连击(升级版)

题目描述

\(1, 2,\ldots, 9\)\(9\) 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 \(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\)


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


题解

这题审题太容易出错了 我以为是一个三位数 1~9不能重复 结果是三个三位数 所有位上的数字都不能重复
这题掌握的一个新知识 segmentation fault 有可能是scanf里面忘加&号了

#include <bits/stdc++.h>

using namespace std;

int a[11], b1, b2, b3, k1, k2, k3, l, ans;

int main()
{
    scanf("%d%d%d", &k1, &k2, &k3);
    for (int i = 1; i <= 1000 / k3; i ++ ) //这里i<=1000/k3 是因为最大倍数是k3 所以在三位数内我们能取的最大数值就是1000/k3
    {
        b1 = i * k1;
        b2 = i * k2;
        b3 = i * k3;
        if (b2 > 999 || b3 > 999) break;
        //分别记录一下每个三位数每一位数字的使用情况
        for (int j = 1; j <= 3; j ++ )
        {
            a[b1 % 10] ++ ;
            b1 /= 10;
        } 
        for (int j = 1; j <= 3; j ++ )
        {
            a[b2 % 10] ++ ;
            b2 /= 10;
        }
        for (int j = 1; j <= 3; j ++ )
        {
            a[b3 % 10] ++ ;
            b3 /= 10;
        }
        //判断每个数字有没有过多使用 如果过多使用 标记一下防止后面输出了 并退出循环 
        for (int j = 1; j <= 9; j ++ )
        {
            if (a[j] != 1)
            {
                l = 1;
                break;
            }
        }
        //对a数组清零方便下次循环使用 
        for (int j = 1; j <= 9; j ++ ) a[j] = 0;
        if (!l) //如果该循环内没有被标记 输出三个数组
        {
            printf("%d %d %d\n", i * k1, i * k2, i * k3); //注意b1 b2 b3已经被改变了 这里要重新输入三个三位数
            ans ++ ; //记录方案数 方便无解的时候输出no 
        }
        else l = 0; //标记清空 
    }
    if (!ans) puts("No!!!"); //无解的情况

    return 0; 
}

法二

利用stl库内的next_permutation函数实现
题目有A B C 三个比例关系
那么我们可以利用1~9内的数字 将所有三位数全排列 找到其中符合题目要求的点 输出
通过b3[9] 1~9数字排列 这样的全排列 我们就可以满足题目要求的 所有的三位数位上数字都不重复
妙!

#include <bits/stdc++.h>

using namespace std;

int b3[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; //将所有可能用到的数字罗列出来
int main()
{
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    int ans = 0;
    do{
        int a1 = 100 * b3[0] + 10 * b3[1] + b3[2];
        int b1 = 100 * b3[3] + 10 * b3[4] + b3[5];
        int c1 = 100 * b3[6] + 10 * b3[7] + b3[8];
        if ((a1 * b == b1 && a1 * c == c1) || (a1 == a && b1 == b && c1 == c))
        {
            ans ++ ;
            printf("%d %d %d\n", a1, b1, c1);
        }
    }while (next_permutation(b3, b3 + 9));

    if (!ans) puts("No!!!");

    return 0;
}
posted @ 2024-04-16 16:50  MsEEi  阅读(37)  评论(0)    收藏  举报