用1,2,3……,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3.输出所有解。

#include<stdio.h>#include<time.h>intmain(){inta,b,c,d,e,f,g,h,i;for(a=1;a<10;a++)for(... #include<stdio.h>
#include<time.h>
int main()
{
int a,b,c,d,e,f,g,h,i;
for(a=1;a<10;a++)
for(b=1;b<10;b++)
for(c=1;c<10;c++)
for(d=1;d<10;d++)
for(e=1;e<10;e++)
for(f=1;f<10;f++)
for(g=1;g<10;g++)
for(h=1;h<10;h++)
for(i=1;i<10;i++)
{
if(a==b||a==c||a==d||a==e||a==f||a==g||a==h||a==i||b==c||b==d||b==e||b==f||b==g||b==h||b==i||c==d||c==e||c==f||c==g||c==h||c==i||d==e||d==f||d==g||d==h||d==i||e==f||e==g||e==h||e==i||f==g||f==h||f==i||g==h||g==i||h==i)
break;
else if((a*100+b*10+c)*2==d*100+e*10+f&&(a*100+b*10+c)*3==g*100+h*10+i)
printf("%d %d %d\n",a*100+b*10+c,d*100+e*10+f,g*100+h*10+i);
else break;
}
printf("Time used=%.21f\n",(double)clock()/CLOCKS_PER_SEC);
return 0;
}
这个是我能想到的程序,但是
理论答案输出:
273 546 819
327 654 981
219 438 657
192 384 576
实际输出:
327 654 981
求大神指教哪里出问题了,还有就是简单方法怎么做,希望步骤能多些注释,谢谢!!

这个是我能想到的程序,但是
展开
 我来答
283802332
推荐于2017-09-15 · TA获得超过3311个赞
知道小有建树答主
回答量:367
采纳率:0%
帮助的人:177万
展开全部

  这道题以前做过, 有点印象


  其实这道题就2个地方要注意, 也是解题关键


  1. abc:def:ghi=1:2:3

  2. 1,2,3……,9组成3个三位数abc,def和ghi,每个数字恰好使用一次


对于第一个地方, 我们可以用1个循环, 加3个变量来实现

就是

for(i = 123; i <= 329; i++)
{
    j = i * 2;    //i的2倍
    k = i * 3;    //i的3倍
}

i 最小只能是123, 最大只能是329(因为最大数字只能是987)


第2个地方的实现, 我们可以用数学的方法来实现

1~9加起来真能是45, 1~9乘起来只能是362880


所以我们可以将前面的i, j, k分别分解出来的9位数字相加, 相乘, 

看最后的结果是不是45,362880



具体代码

//用1,2,3……,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3.输出所有解。

#include <stdio.h>

void result(int num, int &result_add, int &result_mul)
{
    int i, j, k;

    i = num / 100;        //百位
    j = num / 10 % 10;    //十位
    k = num % 10;         //个位

    result_add += i + j + k;    //分解出来的位数相加
    result_mul *= i * j * k;    //相乘
}


int main()
{
    int i, j, k;
    int result_add, result_mul;

    for(i = 123; i <=329; i++)
    {
        j = i * 2;
        k = i * 3;

        result_add = 0;
        result_mul = 1;



        result(i, result_add, result_mul);
        result(j, result_add, result_mul);
        result(k, result_add, result_mul);

        if(result_add == 45 && result_mul == 362880)
            printf("%d %d %d\n", i, j, k);
    }
    return 0;
}



效果:



PS:若有不明白的地方, 请追问

追问
大神可以帮我看下我的程序哪里出错了吗,谢谢!
施勇旺
2017-06-20 · TA获得超过104个赞
知道小有建树答主
回答量:200
采纳率:0%
帮助的人:72.8万
展开全部

问题出在 break;上

以下是可行的实现:

//忽略头

    int a,b,c,d,e,f,g,h,i;
    for(a=1;a<10;a++)
    for(b=1;b<10;b++)
    for(c=1;c<10;c++)
    for(d=1;d<10;d++)
    for(e=1;e<10;e++)
    for(f=1;f<10;f++)
    for(g=1;g<10;g++)
    for(h=1;h<10;h++)
    for(i=1;i<10;i++)
    {
        if(a==b||a==c||a==d||a==e||a==f||a==g||a==h||a==i
                ||b==c||b==d||b==e||b==f||b==g||b==h||b==i
                ||c==d||c==e||c==f||c==g||c==h||c==i||d==e
                ||d==f||d==g||d==h||d==i||e==f||e==g||e==h
                ||e==i||f==g||f==h||f==i||g==h||g==i||h==i)
            continue;
        else{
            if((a*100+b*10+c)*2==d*100+e*10+f&&(a*100+b*10+c)*3==g*100+h*10+i)
                printf("%d %d %d\n",a*100+b*10+c,d*100+e*10+f,g*100+h*10+i);
            else
                continue;
        }
    }
    printf("Time used=%.21f\n",(double)clock()/CLOCKS_PER_SEC);
    
    return 0;

以下是更好的实现:主要是利用一个数组实现集合(set)的功能。

//忽略头
    for(int i = 102;i<333;i++){
        int a[3];
        a[0] = i;
        a[1] = 2*i;
        a[2] = 3*i;


        int hole[10];
        for(int j = 0;j<10;j++)
            hole[j]=0;

        int flag = 1;
        for(int index = 0;index<3 && flag==1 ;index++){
            if(hole[a[index]%10]==0)
                hole[a[index]%10]=1;
            else
                flag=0;
            if(hole[a[index]/10 %10]==0)
                hole[a[index]/10 %10]=1;
            else
                flag=0;
            if(hole[a[index]/100]==0)
                hole[a[index]/100]=1;
            else
                flag=0;

        }
        if(flag==1)
            printf("%d %d %d\n",i,2*i,3*i);
    }
    
    return 0;


目前的最佳答案是一个不错的方法,数学支持如下:

1~9加起来真能是45, 1~9乘起来只能是362880

其实应该反过来说

若9个小于10 的正整数的和为45,积为362880,则这9个数是1,2,3...9的一个排列。

调整法可证。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
丶失丶心丶疯丶
2019-09-07 · TA获得超过102个赞
知道答主
回答量:6
采纳率:0%
帮助的人:5634
展开全部

利用遍历,因为组成的数的最小值为123,最大值为789,同时,三个数满足1:2:3的比例关系,因此只需要遍历abc从最小值到最大值即可。

abc最小值为123,因为abc:ghi=1:3,所以abc的最大值为组成三位数的最大值的三分之一,即329。此时只需要遍历abc从123到329即可。

def=abc*2,ghi=abc*3。

这里你需要知道1-9这9个数的和为45,乘积为362880,只需要判断生成的数每一位满足这个条件即可。

具体程序如下(C++):

#include <bits/stdc++.h>
using namespace std;

int sum(int i)    //求三位数每位相加之和
{
return (int)(i / 100) + (int)(i / 10 % 10) + (int)(i % 10);
}
int mult(int i)    //求三位数每位相乘之积
{
return (int)(i / 100) * (int)(i / 10 % 10) * (int)(i % 10);
}

int main()
{
        //对于1,2,...,9这些书来说,最小的数为123,最大的数为987,因为abc:def:ghi=1:2:3,所以abc的最大值是所组成的最大数的三分之一,即329.
for (int i = 123; i < 987 / 3; i++)
{
int j = i * 2;
int k = i * 3;
if (j <= 987 && k <=987)
{
        //1+2+3+...+9=45,1*2*3*...*9=362880,因此只要判断这三个数每一位相加等于45,相乘等于362880即可。
if(sum(i)+sum(j)+sum(k)==45 && mult(i)*mult(j)*mult(k)==362880)
cout << "i=" << i << "; j=" << j << ";k=" << k << endl;
}
}

system("pause");
return 0;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
wangleiwl2008
2012-05-29 · TA获得超过942个赞
知道小有建树答主
回答量:358
采纳率:0%
帮助的人:312万
展开全部
#include<iostream.h>
void main()
{
int x,y,z;
int str[10];
int s,j=0;//用于冒泡法排序
int a,b,c,d,e,f,g,h,i;
int count,num=0,o=0;//用于计数

x=122;

L1:x++;
y=2*x;z=3*x;

a=x/100;b=(x/10)%10;c=x%10; //把三位数的每一位数字截下来,a,b,c分别为百,十,个位
d=y/100;e=(y/10)%10;f=y%10;
g=z/100;h=(z/10)%10;i=z%10;

str[0]=a;str[1]=b;str[2]=c;str[3]=d;str[4]=e;str[5]=f;str[6]=g;str[7]=h;str[8]=i;
count=9;

for(s=0;s<9;s++)
{
for(j=1;j<9;j++)
{
if(s!=j){

if(str[s]==str[j]||str[s]==0)
{
goto L1;
}
}

}
}

int Num=100*str[6]+10*str[7]+str[8];
int sum=a+b+c+d+e+f+g+h+i;
for(i=0;i<9;i++)
{
if(sum==45){
if(Num<=987)
{
cout<<str[i];
}
if((i+1)%3==0)
{
cout<<" ";
}
}
}
cout<<endl;
if(Num<987){
goto L1;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
ck6698000
2012-06-27
知道答主
回答量:6
采纳率:0%
帮助的人:3.1万
展开全部
#include <stdio.h>
int func(int a)
{
int temp, flag[10] = {1};
for(temp=a%10;a;a/=10,temp=a%10)
if(flag[temp]++ == 1) return 0;
return 1;
}
void main()
{
int base;
for(base=123; base<345; base++)
if(func(base*1000000+base*2*1000+base*3)==1)
printf("%d %d %d\n", base, base*2, base*3);
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(5)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式