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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章