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

本文介绍了如何使用深度优先搜索(DFS)和回溯算法解决一个数学问题,即把1到9这9个数字分成三组,形成三个三位数,使这三个数成1:2:3的比例。通过DFS遍历数字组合,当找到符合条件的三位数时,进行输出。代码示例展示了如何实现这一过程。

新手必做模拟(还没做的建议自己先做)

题目描述

将 1,2,…,9 共9个数分成3组,分别组成3个三位数,且使这3个三位数构成 1:2:3 的比例,试求出所有满足条件的3个三位数。

本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。

输出格式

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

整体思路

很多大佬都是用循环模拟的,在这里我就不赘述了。我想介绍一种新的思路,就是深度优先搜索+回溯

dfs作为一种暴力的算法,在一些只提交答案的题目中很占优势(不必在意时间复杂度)。

这道题的思路就是依次搜索3个三位数上每一位的数字,当搜索完9个数字后,判断是否符合题意并输出就行了。

代码实现看这里

#include<iostream>
using namespace std;
int a[10];//存储三个三位数
bool b[10];//判断数字是否使用过
void print()//判断+输出结果
{
    int b=100*a[1]+10*a[2]+a[3];//计算第一个三位数
    int c=100*a[4]+10*a[5]+a[6];//计算第二个三位数
    int d=100*a[7]+10*a[8]+a[9];//计算第三个三位数
    if(d==3*b&&c==2*b)//如果b:c:d=1:2:3
    {
        for(int i=1;i<=7;i+=3)//循环步长为3
            cout<<a[i]<<a[i+1]<<a[i+2]<<" ";
        cout<<endl;
    }
    return ;
}
void dfs(int k)
{
    int maxn=9;//搜索1-9
    if(k==1)//若是第一个数的百位数
        maxn=3;//搜索1-3
    else if(k==4)//若事第二个数的百位数
        maxn=6;//搜索1-6
    for(int i=1;i<=maxn;i++)
    {
        if(b[i])//如果i被使用过
            continue;//跳过该轮循环
        a[k]=i;
        b[i]=1;//将i标记为使用过
        if(k==9)//如果搜完了
            print();//判断+输出
        else
            dfs(k+1);//继续下一位数搜索
        a[k]=0;//回溯
        b[i]=0;//回溯
    }
    return ;
}
int main()
{
    dfs(1);//从第一个数搜起
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值