Uva725 Division【dfs枚举】【例题7-1】

题目:Division

题意:输入正整数n,按从小到大的顺序输出所有形如abcde/fghij = n的表达式,其中aj恰好为数字09的一个排列(可以有前导0),2≤n≤79

思路:如果分别枚举abcde 和 fghij 是 10!= 3628800

题中已已知商n,所以我们只需枚举除数fghij 即可得出 被除数abcde 。

(1)枚举:利用dfs进行0~9中枚举5位数,

(2)拆分:将枚举的除数和计算得的被除数进行位数拆分,利用标记数组看是否10个数字都出现且不重复,计算除数和被除数的位数和 >10(因为再枚举会越大,永远不符合规则了。)时停止枚举!

参考:入门经典-例7-1-P182

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int visit[10],n,flag[10],sign,prt;
int mark(int value){//拆分数
    int cot = 0;//记录不重复数字
    if(value < 10000){//小于5位数将前置0补上!
        flag[0] = 1;cot++;
    }
    while(value){//拆分数字
        flag[value%10] = 1;//标记每一位上的数字,用于判断是否重复
        value /= 10;
        cot++;
    }
return cot;}//返回数的位数
bool judge(int a,int b){//判断是否符合规则
    memset(flag,0,sizeof(flag));//用于标记不重复数字
    if(mark(a)+mark(b) > 10) {sign = 1; return false;}//超出10位,不符合
    for(int i=0;i<10;i++){
        if(!flag[i]) return false;//没有出现10位数中的某位,不符合
    }
return true;}
void dfs(int steps,int res){//递归枚举除数
    if(steps == 5){

        int temp = res*n;//被除数 = 除数*商
        if(judge(temp,res))//将被除数和除数进行是否符合规则,符合输出
            { printf("%05d / %05d = %d\n",temp,res,n);prt = 0;}
        return;
    }
    for(int i=0;i<=9;i++){
        if(sign) break;//当被除数和除数的位数和大于10时不再枚举
        if(visit[i] == 0){
            visit[i] = 1;
            dfs(steps+1,res*10+i);
            visit[i] = 0;
        }
    }
}
int main()
{
    int k = 0;
    while(scanf("%d",&n)!=EOF && n){
        if(k)printf("\n");k++;
        memset(visit,0,sizeof(visit));
        sign = 0;prt = 1;
        dfs(0,0);
        if(prt) printf("There are no solutions for %d.\n",n);

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值