1. 程式人生 > >洛谷P1618_三連擊(升級版)

洛谷P1618_三連擊(升級版)

col size 函數 class 篩選 names 由於 while n)

相關:洛谷P1008_三連擊

回顧:1~9共九個數,如何搭配組成三個數a,b,c,使得其比值為1:2:3

算法:a必定為首尾為1,2,3的三位數,通過三重循環得到不同的a值(註意a本身的三個數不可以重復),再分別乘2乘3得到b,c;通過得到a,b,c位數的函數統計1~9出現的次數,當且僅當均為1時才輸出a,b,c

代碼如下:

 1 #include<iostream>
 2 #include<cstring>
 3 #define N 20
 4 using namespace std;
 5 
 6 int sd;//用來表示個位數
 7 int g[10]={};//用來存儲每個數出現的次數 
8 9 void div(int n){ 10 while(n>0){ 11 sd=n%10; 12 n=(n-sd)/10; 13 g[sd]++; 14 } 15 } 16 17 int main(){ 18 int a,b,c; 19 for(int i=1;i<=3;i++){ 20 for(int j=1;j<=9;j++){ 21 if(j==i) continue; 22 else{ 23 for
(int k=1;k<=9;k++){ 24 if(k==i||k==j) continue; 25 else{ 26 a=i*100+j*10+k; 27 b=a*2; 28 c=a*3; 29 div(a); 30 div(b); 31 div(c);
32 } 33 if(g[1]==1&&g[2]==1&&g[3]==1&&g[4]==1&&g[5]==1&&g[6]==1&&g[7]==1&&g[8]==1&&g[9]==1){ 34 cout << a << " " << b << " " << c << endl; 35 } 36 memset(g,0,sizeof(g)); 37 } 38 } 39 40 } 41 42 } 43 return 0; 44 45 }

再來看升級版,給定比值A,B,C,求出所有的解

思路1:想要類比1008給定a的百位i的範圍,但是由於ABC值均不確定,放棄

思路2:直接枚舉所有可能的a值,且由於A<B<C,a的首位一定小於等於7,三層循環求出所有可能的a值,再分別求出理論中的b,c值,如果b,c為小於1000的整數,且a,b,c所用數字為1~9,符合條件,輸出

如果所有可能的情況都不符合,無解,輸出"No!!!"

為什麽想到直接枚舉所有情況呢?因為看似很蠢沒有進行篩選,但實際上總共情況也不會超過10的立方,依舊是很小的數量級,因而不必費力直接暴力循環即可。

下為AC代碼:

 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstring>
 4 using namespace std;
 5 int sd;
 6 int g[10]={};
 7 
 8 void div(double n){
 9     while(n>0){
10         sd=(int)n%10;
11         n=n/10;
12         g[sd]++;
13     }
14 }
15 int main(){
16     int A,B,C;
17     cin >> A >> B >> C;
18     double a,b,c;
19     bool isSolution=false;
20     for(int i=1;i<=7;i++){
21         for(int j=1;j<=9;j++){
22             if(i==j)  continue;
23             else
24                 for(int k=1;k<=9;k++){
25                     if(k==i||k==j)  continue;
26                     else{
27                         a=i*100+j*10+k;
28                         b=a/A*B;
29                         if(b!=floor(b)||b>=1000)  continue;
30                         else{
31                             c=a/A*C;
32                             if(c!=floor(c)||c>=1000)  continue;
33                             else{
34                                 div(a);  div(b);  div(c);
35                                 if(g[1]==1&&g[2]==1&&g[3]==1&&g[4]==1&&g[5]==1&&g[6]==1&&g[7]==1&&g[8]==1&&g[9]==1){
36                                     cout << a << " " << b << " " << c << endl;
37                                     isSolution=true;    
38                                 }
39                             }
40                         }
41                     }
42                     memset(g,0,sizeof(g));    
43                 }
44         }    
45     }
46     if(!isSolution)  cout << "No!!!" << endl;
47     return 0;    
48 } 

洛谷P1618_三連擊(升級版)