组合三位数之二——C实现

题目描述:

把1,2,3,4,5,6,7,8,9,组成三个三位数(每个数只能用一次),第二个数是第一个数的2倍,第三个数是第一个数的3倍,这三个三位数各是多少?答案可能有很多组,请按第一个数的升序顺序输出每组的三个三位数。 

输入:

样例输出:

192 384 576
219 438 657
...........
/**********解题思路*************/
/*
1.把可能的三位数按从小到大的顺序存入数组中;
2.由于结果是按升序顺序输出,且每一行也是升序,所以可以按上面的数组去顺序寻找每一组数;
3.在找到的每个数中,个位,十位,百位不能相同,且不能包含0;
4.第二个数是第一个数的2倍,第三个数是第一个数的3倍;
5.找到的三个数每个数的位数都不同。
*/
/************直接上代码************/

#include <stdio.h>
#include <stdlib.h>

#define MAX 865                  //稍微思考一下,该题最小的数为123,最大的数为987,所以共有987 - 123 + 1 = 865个数
int iden(int num);                   //个位,十位,百位,不能相同。输入一个三位整数,有相同的返回1,否则返回0.
int iden_plus(int num1, int num2, int num3);  //每个数只能用一次,即每个数的个位,十位,百位都要不同,且不能有数字0。输入3个3位整数,有相同的返1,否则返回0.
int main(void)
{
  int num[MAX];
  int num1, num2, num3;

//生成123~987之间的整数。ps:当然,为了减少循环,你可以限制一些规则,比如,三位数中的三个数字不能有相同的,不能有数字0等等,这里限制规则多了之后,后面判断就少

  for(int i = 0; i < MAX; i++)       
  {
    num[i] = 123 + i;
  }

//从前到后依次选取3个数,因此第一个数最大选取到倒数第3个,故循环判断条件为:MAX - 2
  for(int i = 0; i < MAX - 2; i++)
  {
    num1 = num[i];               //把选取的第一个数给num1
    if(iden(num1))           //判断num1中的个位,十位,百位不能相同。PS:对最外层加的判断条件越多,循环的次数越少,比如:可以加上num1中不能有0.
      continue;
    for(int j = i + 1; j < MAX - 1; j++)        //选取第二个数,因为题目要求第二个数是第一个数的2倍,所以第二个数一定大于第一个数。
    {
      num2 = num[j];              //把选取的第二个数给num2
      if(num1 * 2 != num2 || iden(num2))    //num2必须为num1的2倍,且num2中的个位,十位,百位不能相同。
        continue;
      for(int k = i + j + 1; k < MAX; k++)      //选取第三个数
      {
        num3 = num[k];           //把第三个数赋给num3
        if(num1 * 3 != num3 || iden(num3))  //第三个数为第一个数的3倍,且num3中的个位,十位,百位不能相同。
          continue;

        if(!(iden_plus(num1, num2, num3)))  //num1,num2,num3中的位,十位,百位不能相同,且不能有数字0.
          printf("%d %d %d\n", num1, num2, num3);
      }
    }
  }

return 0;
}

int iden(int num)
{
  int arry[3];
  for(int i = 0; i < 3; i++)
  {
    arry[i] = num % 10;
    num /= 10;
  }
  for(int i = 0; i < 2; i++)
  {
    for(int j = i + 1; j < 3; j++)
    if(arry[i] == arry[j])
      return 1;
  }
  return 0;
}

int iden_plus(int num1, int num2, int num3)
{
  int num[9];
  for(int i = 0; i < 3; i++)
  {
    num[i] = num1 % 10;
    num1 /= 10;
  }
  for(int i = 3; i < 6; i++)
  {
    num[i] = num2 % 10;
    num2 /= 10;
  }
  for(int i = 6; i < 9; i++)
  {
    num[i] = num3 % 10;
    num3 /= 10;
  }
  for(int i = 0; i < 8; i++)
  {
    if(num[i] == 0)
      return 1;
    for(int j = i + 1; j < 9; j++)
    {
      if(num[i] == num[j] || num[j] == 0)
      return 1;
    }
  }

  return 0;
}

/*

Ps:在网上找到很多代码,虽然看着很高大上,效率很高,但是没有解释,自己理解着太费劲,在这里愚者奉上自己对这道题的理解,oj上已经通过,但是效率不高,希望对大家有所帮助,有效率更高的代码,大家可以再一块学习!

*/

转载于:https://www.cnblogs.com/star-491849224/p/11266009.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值