枚举之除法问题

刚翻到<<算法竞赛入门经典(第2版)>>,看到上面有一道这个题,感觉不错,记录以下;

题目为:

输入正整数n,按从小到大的顺序输出所有形如abcde/fghij = n的表达式,其中a~j恰好 为数字0~9的一个排列(可以有前导0),2≤n≤79。
样例输入:
62
样例输出:
79546 / 01283 = 62
94736 / 01528 = 62

分析:本题有两种解法,1:使用排列组合,然后判断x*y是否和n相等即可,然而其运算速度会相当的慢,因为要计算10!,虽然判断比较简单,但是不好

2:第二种就是枚举了,因为n>2,所以被除数一定是大于除数的,所以被除数可以从12345开始,到98765结束,

其过程是已知x和n,只需判断x%n是否等于0,如果等于0,则y符合条件,记录下y的每一位数字,(用来判断数字是否相同),然后还需要记录下x的每一位数子,其实可以用一个数组即可.然后就是去除含有相同数子的组合,最后输出符合条件的组合即可.

代码如下

#include <bits/stdc++.h>

using namespace std;
int main()
{
    int n,x,y,m;//
    int i,j,flag;//flag相当于一个bool变量,用于判断数子是否有相同的
    int a[10];
    while(1)//我设置的无限循环,如有其它需要请改变量即可
    {
    scanf("%d",&n);
    for(x=12345;x<=98765;x++)
    {
       memset(a,0,sizeof(a));
        flag = 1;
        m = x;
        if(x%n== 0)                        //记录y的各个位
        {

            y = x/n;
            for(i=4;i>=0;i--)
            {
                a[i] = y%10;
                y = y/10;
            }
        }

        for(i=9;i>=5;i--)                //记录x的各个位
        {
            a[i] = m%10;
            m = m/10;

        }

        for(i=0;i<9;i++)                //判断有没有重复的
        {
            for(j=i+1;j<=9;j++)
            {
                if(a[i] == a[j])
                {
                    flag = 0;
                    break;
                }
            }
            if(flag ==0)
                break;
        }

        if(flag==1)
        {
            for(i=5;i<=9;i++)
                printf("%d",a[i]);
            printf("/");
            for(i=0;i<5;i++)
                printf("%d",a[i]);
            printf("=%d\n",n);
        }
    }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/HWT_ZZU/article/details/84060263
今日推荐