三連擊(洛谷 P1008)

題目描述

 將 1,2,...,9 共 9 個數分成三組,分別組成三個三位數,且使這三個三位數構成 1:2:3 的比例,試求出所有滿足條件的三個三位數。 

輸入輸出格式

 輸入格式:沒有輸入。
輸出格式:若干行,每行 3 個數位。 按照每行第一個數位升序排列。

我的解法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;

// 將 i 分別乘以 2 和 3,若這兩個三位數都滿足:(1) 自身沒有重複的數字 (2) 與 i 沒有重複的數字 (3) 不包含 0 這個數字 ,則輸出
int main ()
{
for (int i=123; i<=329; i++)
{
set<int> test1, test2, test3;
set<int> a {i/100, i/10%10, i%10};
int double_i = i*2, triple_i = i*3;
set<int> b {double_i/100, double_i/10%10, double_i%10};
set<int> c {triple_i/100, triple_i/10%10, triple_i%10};
set_intersection (a.begin (), a.end (), b.begin (), b.end (), inserter (test1, test1.begin ()));
set_intersection (a.begin (), a.end (), c.begin (), c.end (), inserter (test2, test2.begin ()));
set_intersection (c.begin (), c.end (), b.begin (), b.end (), inserter (test3, test3.begin ()));
if (test1.empty () && test2.empty () && test3.empty () && a.count (0)==0 && b.count (0)==0 && c.count (0)==0 && a.size ()==3 && b.size ()==3 && c.size ()==3)
cout << i << "" << double_i <<" " << triple_i << endl;
}
return 0;
}

別的解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<cstdio>
#include<cstring>
int i,j,v;bool a [10];//a [i] 表示第 i 个数已经用过了
int main ()
{
for (i=192;i<=327;i++)// 第一个数最小 192,最大 327。其实不知道的情况下简单来说是从 123-329 的但是算出来是最值就稍微改了下下
{
memset (a,0,sizeof (a));v=0;// 清零
a [i%10]=a [i/10%10]=a [i/100]=a [i*2%10]=a [i*2/10%10]=a [i*2/100]=a [i*3%10]=a [i*3/10%10]=a [i*3/100]=1;// 统计数字,赋值所有数组 1;
for (j=1;j<=9;j++) v+=a [j];//v 表示 1-9 这些数字是否全部齐了,如果有相同的数,就会缺某个数组导致得数 < 9;
if (v==9) printf ("% d % d % d\n",i,i*2,i*3);// 如果齐了就输出
}
return 0;
}
// 以上代码来自洛谷题解作者:Kelin

用到的知識點

memset:作用是在一段記憶體塊中填充某個給定的值,它是對較大的結構體或陣列進行清零操作的一種最快方法,清空后換為自己給定的值,可以是符號。

C++ 刷題总览

三連擊(洛谷 P1008)
刷题检讨 —(1) 线性表
刷题检讨