zoukankan      html  css  js  c++  java
  • C语言程序设计100例之(33):加法算式

    例33    加法算式

    问题描述

    看这个加法算式:

    ☆☆☆ + ☆☆☆ = ☆☆☆

    如果每个五角星代表 1 ~ 9 的不同的数字。

    这个算式有多少种可能的正确填写方法?

    173 + 286 = 459

    295 + 173 = 468

    173 + 295 = 468

    183 + 492 = 675

    以上都是正确的填写法!

            注意:111 + 222 = 333 是错误的填写法!因为每个数字必须是不同的! 也就是说:1~9中的所有数字,每个必须出现且仅出现一次!不包括数字“0”!

            另外,满足加法交换率的式子算两种不同的答案。

    输入格式

            无输入。

    输出格式

            一个整数,表示可能的算式总数。

            (1)编程思路。

            对1-9进行全排列,然后检查每种排列是否满足加法等式要求。

    (2)源程序。

    #include <stdio.h>

    int cnt=0;

    void dfs(int a[10],int pos)

    {

           if(pos>9)

           {

                      int num1=a[1]*100+a[2]*10+a[3];

                      int num2=a[4]*100+a[5]*10+a[6];

                      int num3=a[7]*100+a[8]*10+a[9];

                      if (num1+num2==num3)

                {

     //             printf("%d + %d = %d ",num1,num2,num3);

                    cnt++;

                }

          }

          else

               for(int i=pos;i<=9;i++)

               {

                  int temp = a[i];

                  a[i] = a[pos];

                  a[pos] = temp;

                  dfs(a,pos+1);      // 递归

                  temp = a[i];

                  a[i] = a[pos];

                  a[pos] = temp;

            }

    }

    int main()

    {

        int a[10]={0,1,2,3,4,5,6,7,8,9};

        dfs(a,1);

        printf("%d ",cnt);

        return 0;

    }

    习题33

    33-1  排座位

    问题描述

            有3个A国人、3个B国人和3个C国人坐成一排照相。要求任意两个同一国籍的人不能坐在一起。例如,“A1、B1、A3、B2、C1、B3、C2、A2、C3”就是一种可行的坐法,而“A1、B1、A3、B2、C1、B3、C2、C3、A2”就不满足要求,因为此时坐在第7和第8两个位置的人都是C国人。

            求所有位置安排的不同方案总数?

    输入格式

            无输入。

    输出格式

            一个整数,表示可行的位置安排总数。

         (1)编程思路。

            不妨将9个人分别编号为11、12、13、21、22、23、31、32、33,这样编号后,编号十位数相同的人一定是同一个国籍。对{11,12,13,21,22,23,31,32,33}这9个数进行全排列,然后判断每种排列是否符合要求。

        (2)源程序。

    #include <stdio.h>

    int cnt=0;

    int judge(int a[10])  // 判断同一个国家的两个人是否挨着

    {

        for (int i=1;i<=8;i++)

        {

           if(a[i]/10==a[i+1]/10) return 0;

        }

        return 1;

    }

    void dfs(int a[10],int pos)

    {

        if(pos>9)

           {

               if (judge(a)==1)

            {

                  cnt++;

            }

        }

        else

           for(int i=pos;i<=9;i++)

           {

              int temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

              dfs(a,pos+1);      // 递归

              temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

           }

    }

    int main()

    {

        int a[10]={0,11,12,13,21,22,23,31,32,33};

        dfs(a,1);

        printf("%d ",cnt);

        return 0;

    }

    33-2  猜算式

    问题描述

            看下面的算式:□□ x □□ = □□ x □□□ 它表示:两个两位数相乘等于一个两位数乘以一个三位数。如果没有限定条件,这样的例子很多。

            给出限定是:这9个方块,表示1~9的9个数字,不包含0。该算式中1至9的每个数字出现且只出现一次!

    比如:

    46 x 79 = 23 x 158

    54 x 69 = 27 x 138

    54 x 93 = 27 x 186

            请编程,输出所有可能的情况! 注意:左边的两个乘数交换算同一方案,不要重复输出!

    输入格式

            无输入。

    输出格式

            输出所有满足要求的乘法等式,每个等式占1行。

    输入样例

            无输入

    输出样例

    46*79=23*158

    54*69=27*138

    54*93=27*186

    ……  (省略的其他解的情况)

          (1)编程思路1。

            对1-9进行全排列,然后检查每种一次填入9个方框后是否满足乘法等式要求。为了不重复输出,输出时保证左边的两个乘数小数在前,大数在后。

          (2)源程序1。

    #include <stdio.h>

    void dfs(int a[10],int pos)

    {

           if(pos>9)

           {

                      int n1=a[1]*10+a[2];

                      int n2=a[3]*10+a[4];

                      int n3=a[5]*10+a[6];

                      int n4=a[7]*100+a[8]*10+a[9];

                      if (n1<n2 && n1*n2==n3*n4)

                    {

                       printf("%d*%d=%d*%d ",n1,n2,n3,n4);

                   }

            }

            else

               for(int i=pos;i<=9;i++)

               {

                  int temp = a[i];

                  a[i] = a[pos];

                  a[pos] = temp;

                  dfs(a,pos+1);      // 递归

                  temp = a[i];

                  a[i] = a[pos];

                  a[pos] = temp;

            }

    }

    int main()

    {

        int a[10]={0,1,2,3,4,5,6,7,8,9};

        dfs(a,1);

        return 0;

    }

          (3)编程思路2。

            设乘法算式中从左到右的四个数分别为a、b、c、d,用三重循环对a、b、c这三个两位数进行穷举。其中10≤a≤97,a+1≤b≤98, 10≤c≤98。对穷举的每种情况,若a和b的积能整除c,则计算出d,然后判断这4个数中1~9这9个数字是否全部出现。

            为判断数字1~9是否都出现。定义数组int hash[10],其元素初始值全为0,hash[i]=0表示数字i未出现,数字i出现过,置hash[i]=1。

        (4)源程序2。

    #include <stdio.h>

    int main()

    {

           int a,b,c,d,i;

           int hash[10];

           for (a=10; a<=97; a++)

             for (b=a+1; b<=98; b++)

               for (c=10; c<=98; c++)

            {

                if ((a*b)%c==0)

                {

                    d=a*b/c;

                    for (i=0;i<10;i++)

                        hash[i]=0;

                    hash[a/10]=1; hash[a%10]=1;

                    hash[b/10]=1; hash[b%10]=1;

                    hash[c/10]=1; hash[c%10]=1;

                    hash[d/100]=1; hash[d/10%10]=1; hash[d%10]=1;

                    for (i=1;i<=9;i++)

                        if (hash[i]==0) break;

                    if (i>9)

                        printf("%d*%d=%d*%d ",a,b,c,d);

                }

            }

           return 0;

    }

    33-3  三个3位平方数

    问题描述

            将1、2、3、4、5、6、7、8、9九个数字分成三组,每组三个数字构成一个三位数,要求每组中的三位数都组成一个平方数。

            试求出满足要求的3个三位数。

    输入格式

            无输入。

    输出格式

            三个从小到大排列的3位整数。

          (1)编程思路1。

            仿照例33的做法,生成1~9的全排列,再判断全排列的每种情况构成的3个三位数是否都是平方数。

          (2)源程序1。

    #include <stdio.h>

    #include <math.h>

    void dfs(int a[10],int pos)

    {

           if(pos>9)

           {

                int num1=a[1]*100+a[2]*10+a[3];

                int num2=a[4]*100+a[5]*10+a[6];

                int num3=a[7]*100+a[8]*10+a[9];

                int i=(int)sqrt(1.0*num1);

                int j=(int)sqrt(1.0*num2);

                int k=(int)sqrt(1.0*num3);

                if (i*i==num1 && j*j==num2 && k*k==num3)

                {

                   printf("%d  %d  %d ",num1,num2,num3);

                }

          }

         else

               for(int i=pos;i<=9;i++)

               {

                  int temp = a[i];

                  a[i] = a[pos];

                  a[pos] = temp;

                  dfs(a,pos+1);        // 递归

                  temp = a[i];

                  a[i] = a[pos];

                  a[pos] = temp;

            }

    }

    int main()

    {

        int a[10]={0,1,2,3,4,5,6,7,8,9};

        dfs(a,1);

        return 0;

    }

          源程序1运行后输出如下的结果。

    361  529  784

    361  784  529

    529  784  361

    529  361  784

    784  361  529

    784  529  361

            这6个结果按从小到大排列后,本质是一个结果。因此,程序中还需进行去重。

          (3)编程思路2。

            按思路1虽然可以求出3个3位平方数,但并不是这题理想的解法。

            实际上,3位平方数最多有21个(11的平方到31的平方)。因此我们可以先求出所有三位平方数,并且将这些数中出现数字0或存在重复数字的数去掉,例如121、144等。这样的三位平方数一定少于21个,设有cnt个。再在这cnt个数中任意选取3个数进行组合,看每种组合中的3个3位数的数字是否全部不相同,正好1~9每个数字出现一次。

            为判断数字1~9是否都出现。定义数组int hash[10],其元素初始值全为0,hash[i]=0表示数字i未出现,数字i出现过,置hash[i]=1。

        (4)源程序2。

    #include <stdio.h>

    int a[3];

    int cnt=0;

    void dfs(int p[],int pos,int num)

    {

        if (pos==3)

        {

            int hash[10],i;

            for (i=0;i<10;i++)

                hash[i]=0;

            hash[a[0]/100]=1; hash[a[0]/10%10]=1; hash[a[0]%10]=1;

            hash[a[1]/100]=1; hash[a[1]/10%10]=1; hash[a[1]%10]=1;

            hash[a[2]/100]=1; hash[a[2]/10%10]=1; hash[a[2]%10]=1;

            for (i=1;i<=9;i++)

                if (hash[i]==0) break;

            if (i>9)

                 printf("%d %d %d ",a[0],a[1],a[2]);

            return;

        }

        if(3-pos>cnt-num+1) return ;

        for(int i=num;i<cnt;i++)

        {

            a[pos]=p[i];

            dfs(p,pos+1,i+1);

        }

    }

    int main()

    {

        int p[20];

        int i;

        for (i=11;i<=31;i++)

        {

            int a=(i*i)/100;

            int b=(i*i)/10%10;

            int c=(i*i)%10;

            if (a==0 || b==0 ||c==0) continue;

            if (a==b || a==c || b==c) continue;

            p[cnt++]=i*i;

        }

        dfs(p,0,0);

        return 0;

    }

  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Mysql 使用 select into outfile
    Mysql 使用CMD 登陆
    使用Clean() 去掉由函数自动生成的字符串中的双引号
    Get Resultset from Oracle Stored procedure
    获取引用某个主键的所有外键的表
    Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
    添加MySql Metat Database 信息
    at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
  • 原文地址:https://www.cnblogs.com/cs-whut/p/13857502.html
Copyright © 2011-2022 走看看