蓝桥杯 排列

排列(permutation)

        用1,2,3, ... ,9组成3个三位数abc, def和ghi,每个数字恰好使用一次,要求abc:def:ghi = 1:2:3。输出所有解。提示:不必太动脑筋。

分析:

        1. 两个重要条件:

        ①abc:def:ghi=1:2:3    ②1~9 9个自然数组成abc def ghi 三个三位数,且每个数字恰好使用一次。

        2. 由题意,def是abc的两倍,ghi是abc的三倍,结合1. 中条件,可知abc最小是123,最大是329(因为要满足abc def ghi是三位数)

        3. 因为1~9都要出现且仅出现一次,因此验证每种解是否成立时,只需验证分离出的9位数之和为45,且9位数之积为362880即可,这也就是第二种方法中不必太动脑筋体现的地方。

源代码:

法一:暴力枚举法:


#include <stdio.h>  
int main()  
{  
    int i, j, k;  
    int i1, i2, i3;  
    int j1, j2, j3;  
    int k1, k2, k3;  
    int c, count;
    for (i = 123; i <= 329; i++)
    {  
        j = i*2;  
        k = i*3;  
        i1 = i/100, i2 = i/10%10; i3 = i%10;  
        j1 = j/100, j2 = j/10%10; j3 = j%10;  
        k1 = k/100, k2 = k/10%10; k3 = k%10;          
        for (c = 1; c != 10; c++)                        //此循环验证1-9 9个数字是否恰好使用了一次 
	{
            count = 0;                                   //每轮count置初值0,如果i1~k3有重复数字,count>=2,跳出  
            if (c == i1)  
                count++; 
            if (c == i2)  
                count++;  
            if (c == i3)  
                count++;  
            if (c == j1)  
                count++;  
            if (c == j2)  
                count++;  
            if (c == j3)  
                count++;  
            if (c == k1)  
                count++;  
            if (c == k2)  
                count++;  
            if (c == k3) 
                count++;  
            if (count > 1)  
                break;  
        }  
        if (c == 10 && i2 != 0 && i3 != 0 && j2 != 0 && j3 != 0 && k2 != 0 && k3 != 0)         //count=1的情况下c=10,且三个三位数没有含0的位,输出这三个三位数 
            printf("%d %d %d\n", i, j, k);  
    }         
    return 0;  
}法二:利用循环,相对不必太费脑筋的做法 


#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;                                        //i,j,k分别为三位数abc def ghi 
    int result_add,result_mul;                        //分解出的个位数相加和相乘的结果 
    for(i=123;i<=329;i++)                             //i最小只能是123, 最大只能是329(因为最大数字只能是987,且每个数字恰好使用一次)
    {
        j=i*2;                                        //j是i的2倍
        k=i*3;                                        //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)      //1-9恰好使用一次时满足1+2+...+9=45,9!=362880,此时输出满足条件的i,j,k 
            printf("%d %d %d\n",i,j,k);
    }
    return 0;
}
法三:循环数组综合利用,更清晰直观


#include <stdio.h>
int fun(int t[],int i)                    //分解三位数,数组相应位置值加一 
{
	t[i/100]++;
	t[(i%100)/10]++;
	t[i%10]++;
}

void clearArray(int t[],int l)            //将数组置为0 
{
	int i;
 	for(i=0;i<l;i++)
		t[i]=0;     
}

int main()
{
    int a[10]={0};
    int i,j,k,p;                                  //i,j,k分别为三位数abc def ghi 
    for(i=123;i<329;i++)                          //i最小只能是123, 最大只能是329(因为最大数字只能是987)
    {
		j=i*2;                            //j是i的2倍 
		k=i*3;                            //k是i的3倍 
		fun(a,i);                         //依次分解i,j,k 
		fun(a,j);
		fun(a,k);
		for(p=1;p<10;p++)
		{
       //如果数组元素值不全为1,则将数组元素全部置0 
        	if(a[p]!=1)
        	{
         		clearArray(a,10);
         		break;
        	}
       	} 
       	if(p==10)
       	{
        	printf("%d %d %d\n",i,j,k);
       	}   
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值