zoukankan      html  css  js  c++  java
  • 算法入门经典-第七章 例题7-1 除法


    题意简述:输入正整数n,用0~9这10个数字不重复组成两个五位数abcde和fghij,使得abcde/fghij的商为n,按顺序输出所有结果。如果没有找到则输出“There are no solutions for N.”。这里2<=n<=79。

    样例输入: 62

    样例输出:

    79546/01238=62

    94736/01528=62

    法一:

    #include<stdio.h>
    #include<string.h>
    int main()
    {
        int n; //x/y=n x用abcde表示,若整除n,求出y,而后用fghij表示Y,看是否重复数字 
        while(~scanf("%d",&n))
        {
            int a,b,c,d,e;
            for(a=0;a<=9;a++)
                for(b=0;b<=9;b++)
                    for(c=0;c<=9;c++)
                        for(d=0;d<=9;d++)
                            for(e=0;e<=9;e++)
                            {
                                int x=a*10000+b*1000+c*100+d*10+e;
                                if(!(x%n)){
                                int y=x/n;
                                int f=y/10000,g=y/1000%10,h=y/100%10,i=y/10%10,j=y%10;
                                int buf[10];
                                buf[0]=a,buf[1]=b,buf[2]=c,buf[3]=d,
                                buf[4]=e,buf[5]=f,buf[6]=g,buf[7]=h,
                                buf[8]=i,buf[9]=j;
                                for(int k=0;k<9;k++){
                                    for(int t=k+1;t<10;t++)if(!(buf[k]-buf[t]))break;//只跳出了一个循环 
                                    if(t!=10)break;//判断是不是中途中断了循环 
                                }
                                if(k==9)
                                    printf("%d%d%d%d%d/%d%d%d%d%d=%d
    ",a,b,c,d,e,f,g,h,i,j,n);
                                }
                            }
        }
        return 0;
    }

     

    法二:

    问题分析:没有什么好办法,就暴力枚举吧!不过还是要下点功夫,否则10!的计算量是不可想象的。

    1.因为n>=2,且abcde=fghij×n,满足abcde>fghij。若a=0,则fghij的最小值为12345,abcde<fghij,矛盾。所以a≠0。

    2.因为a≠0,所以12345<=abcde<=98765,01234<=fghij。

    3.因为2≤n,且abcde≤98765,那么fghij = abcde/n,得fghij≤98765/2=49382,所以01234≤fghij≤49382。

    4.因为12345≤abcde≤98765,且01234≤fghij≤49382,所以用fghij进行枚举范围比较小。(这是在任意的n的条件下得出的结论)

    5.对于给定的n,因为abcde≤98765,那么fghij = abcde/n,得fghij≤98765/n。结论:01234≤fghij≤98765/n。

    #include <stdio.h>  
    #include <memory.h>  
      
    #define DIGITNUM 10  
    //这里判断两个数的每一位都不相同我用的是采用一个数组,然后把每一个数字在对应的数组中的位置的元素换成1,然后判断数组中的元素是否全部都为1即可。
    //数组下标代表0,1,2,3,4,5,6,7,8,9

    int check(int abcde, int fghij) { int used[DIGITNUM], d; memset(used, 0, sizeof(used)); if(fghij < 10000) used[0] = 1; while(abcde) { d = abcde % 10; if(used[d]) //如果该位已被占过,则说明abcde与fghij有一位的数字重复 return 0; used[d] = 1; abcde /= 10; } while(fghij) { d = fghij % 10; if(used[d]) return 0; used[d] = 1; fghij /= 10; } return 1; } int main(void) { int n, abcde, count, caseflag=0, end, i; while(scanf("%d", &n) != EOF && n != 0) { if(caseflag) printf(" "); caseflag = 1; count = 0; end = 98765 / n; for(i=1234; i<=end; i++) { abcde = i * n; if(abcde >= 12345 && check(abcde, i)) { printf("%05d / %05d = %d ", abcde, i, n); count++; } } if(count == 0) printf("There are no solutions for %d. ", n); } return 0; }

    法三:

    #include "stdio.h"  
    int judge (int a,int b) {  
        if (a>98765) return 0;  
        int num[10] = {0};  
        if (b<10000) num[0]=1;  
        while (a) {  
            num[a%10] = 1;  
            a /= 10;  
        }   
        while (b) {  
            num[b%10] = 1;  
            b /= 10;  
        }  
        int sum = 0;  
        for (int i = 0; i < 10; i++)  
            if (num[i] != 1)  
                return 0;  
        return  1;  
    }  
    int main () {  
        int n;  
        while (scanf ("%d",&n) !=EOF) {  
            for (int i = 1234; i < 100000; i++) {  
                if (judge(i*n,i))  
                    printf ("%05d / %05d = %d
    ",i*n,i,n);  
            }  
        }  
        return 0;  
    }  

    (效率比较低,与上一种类似)

    法四:手动补齐0

    #include <iostream>
    using namespace std;
    int isright(int,int);
    int main()
    {
        int n,i;
        while(cin>>n)
        {
            for(i=1234; i*n<=98765; i++)
                {if(i<=9876&&i*n>=12345&&isright(i,i*n))//手动补齐0
                    cout<<i*n<<"/0"<<i<<"="<<n<<endl;
            if(i>=10234&&i*n>=56789&&isright(i,i*n))
                cout<<i*n<<"/"<<i<<"="<<n<<endl;
        }}
        return 0;
    }
    int isright(int x,int y) //判断xy是否是由不同的0~9九个数组成的
    {
        int a[10]= {0};
        for(int i=0; i<5; i++)
        {
            a[x%10]++;
            x=x/10;
        }
        for(int i=0; i<5; i++)
        {
            a[y%10]++;
            y=y/10;
        }
        for(int i=0; i<10; i++)
        {
            if(a[i]!=1) return 0;
        }
        return 1;
    }
  • 相关阅读:
    LeetCode 452. 用最少数量的箭引爆气球
    LeetCode 451. 根据字符出现频率排序
    LeetCode 464. 我能赢吗
    LeetCode 2. 两数相加
    @RendSection{"scripts",require:false}的作用
    js中变量含(参数、数组)作用域传递问题
    Web Api通过Route、RoutePrefix等特性设置路由
    SQLserver中存储图片
    RDLC的部署(无法找到Microsoft.ReportViewer.ProcessingObjectModel.dll文件)
    C# 发送Http协议 模拟 Post Get请求
  • 原文地址:https://www.cnblogs.com/is-Tina/p/7470669.html
Copyright © 2011-2022 走看看