P1618 三连击(升级版)

题目描述
将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”。
//感谢黄小U饮品完善题意
输入输出格式
输入格式:

三个数,A B C。
输出格式:

若干行,每行3个数字。按照每行第一个数字升序排列。
输入输出样例

输入样例#1:
复制
1 2 3

输出样例#1:
复制
192 384 576
219 438 657
273 546 819
327 654 981

说明
保证A<B<C

做法1:
让第一个数i从123(最小的三位且数字不重复的数)起循环,一直找到987(最大的三位且数字不重复的数),则第二个数就是i * B/A,第三个数就是i * C/A。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<math.h>
using namespace std;
int main()
{
 double A, B, C;
 int cnt = 0;//计数共输出几次符合的答案
 int num[10];//用num存0-9的数有没有被用过
 cin >> A >> B >> C;
 for (int i = 123; i <= 987; i++)
 //for(int i=(123/a+min(123%a,1))*a;i<=987/a*a;i+=a)
 //有个大佬的循环这么写,说这个式子可以保证所有枚举的i都能被a整除
 //迷茫。同九义汝何秀?
 {
  double tmp1 = B / A;//tmp1存储比例1
  double tmp2 = C / A;//tmp2存储比例2
  if ((int)(log10f(i*tmp1)) == 2 && (int)(log10f(i*tmp2)) == 2)//如果都是三位数则继续,log10f(i*tmp1)可以求出第二个数的位数-1,第三个数同理{
   int b, c;
   b = (int)i*tmp1;//将第二个数强制转换成整型存到b中
   c = (int)i*tmp2;//将第三个数强制转换成整型存到c中
   if ( b == i * tmp1 && c == i * tmp2)//如果整型的b或c和它原来double型的值相等,说明它是整数
   {
    memset(num, 0, sizeof(num));//将计数用的num数组清零(注意要放在循环内)
    int ge_i = i % 10, shi_i = i / 10 % 10, bai_i = i / 100;//计算个位、十位、百位数
    int ge_b = b % 10, shi_b = b / 10 % 10, bai_b = b / 100;//同上
    int ge_c = c % 10, shi_c = c / 10 % 10, bai_c = c / 100;//同上
    num[ge_i] = 1, num[shi_i] = 1, num[bai_i] = 1;//将出现过的数记为1
    num[ge_b] = 1, num[shi_b] = 1, num[bai_b] = 1;
    num[ge_c] = 1, num[shi_c] = 1, num[bai_c] = 1;
    if (num[0]==0&&num[1]==1 && num[2] == 1 && num[3] == 1 && num[4] == 1 && num[5] == 1 && num[6] == 1 && num[7] == 1 && num[8] == 1 && num[9] == 1)
    //如果没有出现0,并且1-9每个数都出现过了,则符合条件
    //这里也可以用一个小循环计算累加和和累乘和,若累加和为45,且累乘和为362880,则1-9每个数都仅用过一次
    {
     printf("%d %d %d\n", i, b, c);
     cnt++;//记录输出次数
    } 
   }
  }
  else
   break;//一旦第二个数或第三个数超过三位数,后面就更不用看了,直接跳出节省时间
 }
 if (cnt == 0)//如果没有解,就输出No!!!
 {
  printf("No!!!\n");
 }
 system("pause");
 return 0;
}

做法2(题解大佬的想法):
运用next_permutation()函数,将1-9的数进行全排列,判断每次排列除的数是否满足比值为A:B:C即可。
这函数挺常用了,为什么我没有想到!

#include<bits/stdc++.h>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
int main()
{
    int A,B,C,h=0;
    cin>>A>>B>>C;
    int t=A*B*C;
    A=t/A;
    B=t/B;
    C=t/C;//哇这个求比例的方法也比我的简便多了
    do{
        if((100*a[1]+10*a[2]+a[3])*A==(100*a[4]+10*a[5]+a[6])*B&&(100*a[1]+10*a[2]+a[3])*A==(100*a[7]+10*a[8]+a[9])*C)//如果符合比例;
        {
            cout<<a[1]<<a[2]<<a[3]<<" "<<a[4]<<a[5]<<a[6]<<" "<<a[7]<<a[8]<<a[9]<<endl;//输出
            h++;
        }
    }while(next_permutation(a+1,a+10));//STL中的下一个排列函数;
    if(h==0) cout<<"No!!!";//没有解输出NO;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章