相关:洛谷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 }