【Uva 題庫解題】C++ 個人解題筆記(一顆星選集) - part 4
===
[TOC]
一篇十題讓你看到爽!
CPE 49 道必考題,資料來源:https://cpe.mcu.edu.tw/environment.php
## 31. All You Need Is Love!
Uva Online Judge:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1134
No Zerojudge :(
題目翻譯(From [Lucky貓](http://web.kshs.kh.edu.tw/academy/luckycat/homework/q10193.htm)):
IBM(International Beautiful Machines)公司發明了一種小玩意兒叫做「愛的算命機」。這台機器會回答你是否非常渴望愛情。這機器運作的情形是:請你輸入一僅含 0 和 1 的字串(稱為 S),機器自己則定義一僅含 0 和 1 的字串(稱為 L,Love 的意思)。然後機器不斷的用 S 去減 L(當然是 2 進位的減法),如果最後可以得到 S = L,代表 S 是用 Love 做成的。如果最後 L > S,代表 S 不是用 Love 做成的。
舉例說明:假設 S = "11011",L = "11"。如果我們不斷的從 S 減去 L,我們可以得到:11011、11000、10101、10010、1111、1100、1001、110、11。所以我們得到 L 了,也就是 S 是用 Love 做的。由於愛的算命機的某些限制,字串不可以有以 0 為開頭的,也就是說 "0010101"、"01110101"、"011111" 這些字串都是不合法的。另外,只有一個位元的字串也是不合法的。
**Input**
輸入的第一列有一個整數 N( N < 10000 ),代表以下有幾組測試資料。每組測試資料 2 列,代表 S1 和 S2 字串,其長度都不會超過 30 個字元。你可以假設所有的字串都是合法的。
**Output**
對每一組測試資料輸出以下其中之一:
Pair #p: All you need is love!
Pair #p: Love is not all you need!
在這裡 p 代表這是第幾組測試資料。如果 S1 和 S2 至少可以找到一個合法的 L,使得 S1 和 S2 都可以用 Love 做成,則輸出第一種訊息。否則,請輸出第二種訊息。請參考 **Sample Output**。
**Sample Input**
```
5
11011
11000
11011
11001
111111
100
1000000000
110
1010
100
```
**Sample Output**
```
Pair #1: All you need is love!
Pair #2: Love is not all you need!
Pair #3: Love is not all you need!
Pair #4: All you need is love!
Pair #5: All you need is love!
```
解題思路:
題目在說要不斷的做 S - L,直到找到一個合法的 L。
所謂合法的 L 就是 S = L。(找 S 是否為 L 的倍數)
若要用一數找出同時對於兩字串都合法的情形,就是用到 GCD。
將二進位字串 S1 S2 轉成十進位 a b(用 `stoi(str, nullptr, 2)`),判斷 a 與 b 的最大公因數(GCD)是否大於 1。
gcd > 1:有共同的 Love 字串。
else:沒愛。
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b){
while (b != 0){
int r = a % b;
a = b;
b = r;
}
return a;
}
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int N;
cin >> N;
string s1, s2;
for (int p = 1; p <= N; ++p){
cin >> s1 >> s2;
int a = stoi(s1, nullptr, 2);
int b = stoi(s2, nullptr, 2);
cout << "Pair #" << p << ": ";
cout << ( gcd(a, b) > 1 ? "All you need is love!" : "Love is not all you need!");
cout << '\n';
}
return 0;
}
```
## 32. Divide, But Not Quite Conquer!
PDF Source:https://onlinejudge.org/external/101/10190.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=e566
題目翻譯:
你在這個問題中的目標是,將某個整數 $n$ 重複除以另一個整數 $m$ ,直到 $n = 1$ ,形成一個數列。我們稱這個數列中的每個數為 $a[i]$ ,假設這個數列共有 $k$ 個數(也就是說你需要進行 $k - 1$ 次連續的除法操作才能讓 $n$ 變成 $1$ )。
你只能在滿足以下限制的情況下擁有這樣的數列:
- $a[1] = n$ ,且對所有 $1 < i \leq k$ 都有 $a[i] = a[i - 1] \div m$
- $a[i]$ 可以被 $m$ 整除(也就是 $a[i] \quad mod \quad m = 0$ ,對所有 $1 \leq i < k$ 皆成立
- $a[1] > a[2] > a[3] > \cdots > a[k]$
例如,若 $n = 125$ 且 $m = 5$ ,你會得到:125、25、5 和 1(你做了三次除法:125 ÷ 5、25 ÷ 5 和 5 ÷ 5)。
因此 $k = 4$ , $a[1] = 125$ 、 $a[2] = 25$ 、 $a[3] = 5$ 、 $a[4] = 1$ 。
若 $n = 30$ 且 $m = 3$ ,你會得到 30、10、3 和 1。但 $a[2] = 10$ ,而 $10 \quad mod \quad 3 = 1$ ,因此此數列不成立,因為它違反了限制 2。當這樣的數列不存在時,我們覺得它既不好玩又很無聊!
注意點:
m 可能為 0 或 1,這兩個情況可在開頭就先排除掉。
範例程式碼:
2025/09/28 修改:部分錯誤,資料型態改成 long long,然後確認一下 m n 條件就可在 Uva Online Judge 上 AC。
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main(){
long long n, m;
while (cin >> n >> m){
if (m <= 1 || n < m) {
cout << "Boring!\n";
continue;
}
if (n == 1) {
cout << "Boring!\n";
continue;
}
vector<long long> nums;
bool isBoring = false;
while (true) {
nums.emplace_back(n);
if (n == 1) break;
if (n % m != 0) {
isBoring = true;
break;
}
n /= m;
}
if (isBoring) {
cout << "Boring!\n";
} else {
for (size_t i = 0; i < nums.size(); ++i) {
if (i > 0) cout << " ";
cout << nums[i];
}
cout << '\n';
}
}
return 0;
}
```
## 33. Simply Emirp
PDF Source:https://onlinejudge.org/external/102/10235.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=d387
題目翻譯:
一個大於 1 的整數,若其唯一的正整數因數為 1 和它本身,則稱為質數(Prime Number)。
質數多年來一直是許多數學家研究的對象。質數在密碼學與編碼理論中也有應用。
你曾試過把一個質數反轉嗎?對於大多數質數來說,反轉後會變成一個合數(例如 43 變成 34)。
Emirp(Prime 的反拼法)是一種質數,其數字反轉後仍為不同的質數。
例如,17 是 Emirp,因為 17 與其反轉後的 71 都是質數。
在本題中,你必須判斷一個數字 $N$ 是「非質數(Non-prime)」、「質數(Prime)」還是「Emirp」。假設 $1 < N < 1000000$ 。
有趣的是,Emirp 對於 NTU 的學生並不陌生。我們已經搭了 199 號與 179 號公車很長一段時間了!
精選單字:
- prime number 質數
- cryptography 密碼學
- composite (n.) (由不同部分組成的)混合物,合成物,綜合體;複合材料,混合材料
- emirp 反質數
解題思路:
用字串輸入 N,設兩變數 `int a, b`,`a` 是原本的數字 N,`b` 為反轉後的數字 N。
可用 `<algorithm>` 內建方法 `reverse(N.begin(), N.end())` 反轉字串。
比較簡單且時間複雜度低的質數篩法可見範例程式碼。
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
bool is_prime(int x){
for (int y = 2; y * y <= x; ++y){
if (x % y == 0){
return false;
}
}
return true;
}
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
string N;
while (cin >> N){
int a = stoi(N);
reverse(N.begin(), N.end());
int b = stoi(N);
if (is_prime(a)){
if (a != b && is_prime(b)){
cout << a << " is emirp.";
}
else{
cout << a << " is prime.";
}
}
else{
cout << a << " is not prime.";
}
cout << "\n";
}
return 0;
}
```
## 34. 2 the 9s
PDF Source:https://onlinejudge.org/external/109/10922.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=d672
題目翻譯:
一個眾所皆知的技巧是:若要判斷一個整數 $N$ 是否為 $9$ 的倍數,可以計算其所有位數的總和 $S$ 。如果 $S$ 是 $9$ 的倍數,那 $N$ 也是。這是一種遞迴式的檢查方式,而要得到 $N$ 是否為 $9$ 的倍數所需遞迴的層數,就稱為 $N$ 的 $9$ 度數(9-degree)。
你的任務是:給定一個正整數 $N$ ,判斷它是否為 $9$ 的倍數;若是,則求出它的 $9$ 度數。
解題思路:
用迴圈替代遞迴,可避免 stack overflow(~~疑?好像有雙關...~~。
因為 N 可能有 1000 位,所以用 string 存。
再來題目要求計算 S,S 是所有「位」數字的和,如 9999:
$S = 9 + 9 + 9 + 9 = 36$
若 $S \quad mod \quad 9 \neq 0$ ,表 S 非 9 的倍數,則直接輸出即可。
那 S 做到 36 還不夠,要繼續做下去,下一個 S = 3 + 6 = 9,做到剩一個 9 就結束。
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
int digitSum(const string& N){
int sum = 0;
for (char c : N){
sum += c - '0';
}
return sum;
}
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
string N;
while (cin >> N && N != "0"){
int degree = 0;
int sum = digitSum(N);
degree++;
while (sum >= 10){
sum = digitSum(to_string(sum));
degree++;
}
if (sum == 9) {
cout << N << " is a multiple of 9 and has 9-degree " << degree << "." << '\n';
} else {
cout << N << " is not a multiple of 9." << '\n';
}
}
return 0;
}
```
## 35. GCD
PDF Source:https://onlinejudge.org/external/114/11417.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=d255
題目翻譯:
給定 N 的值,你必須找到一個值 G。G 的定義如下所示:

這裡的 $GCD(i, j)$ 表示整數 i, j 的最大公因數。
對於那些難以理解求和符號(Sigma)的人來說,G 的意義可從以下程式碼看出:
```cpp=
G=0;
for(i=1;i<N;i++)
for(j=i+1;j<=N;j++)
{
G+=GCD(i,j);
}
/*Here GCD() is a function that finds
the greatest common divisor of the two
input numbers*/
```
範例程式碼:
實測 Uva Online Judge 跟 Zerojudge 都過得了,~~主打一個能過就行~~。
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int N;
while (cin >> N && N != 0){
int G = 0;
for (int i = 1; i < N; ++i){
for (int j = i + 1; j <= N; ++j){
G += __gcd(i, j); // C++ 14
}
}
cout << G << '\n';
}
return 0;
}
```
## 36. Largest Squares
PDF Source:https://onlinejudge.org/external/109/10908.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=e575
題目翻譯:
給定一個由字元組成的矩形網格,你需要找出最大的正方形邊長,使得該正方形內所有字元相同,且該正方形的中心點(兩條對角線的交點)位於位置 $(r, c)$ 。網格的高度和寬度分別為 $M$ 和 $N$ 。網格的左上角和右下角分別用 $(0, 0)$ 和 $(M-1, N-1)$ 來表示。以下是給定的字元網格。已知位置 $(1, 2)$ 之處,最大正方形的邊長為 $3$ 。
abbbaaaaaa
abbbaaaaaa
abbbaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaccaaaaaa
aaccaaaaaa
解題思路:
首先要釐清一件事情,就是有中心的正方形的邊長必為奇數。
在這邊初始化 maxLen 最大邊長可預設為 1,表示只有他自己而已。
之後跑個 for loop,`for (int len = 3; ; len += 2)`,從 3 開始去跑,每次 + 2 確保是奇數的。
內部邏輯就是自訂函數 `is_valid()` 去判斷擴張後是否能成為一個正方形,這部分根據題目條件去對 `is_valid()` 內部做設計。
如果 `is_valid()` true 的時候就更新最大長度,否則直接 `break`。
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
// 檢查中心 (r, c) 為中心、邊長為 len 的正方形是否合法
bool is_valid(const vector<string>& grid, int r, int c, int len, int M, int N) {
char ch = grid[r][c]; // 中心點的字元
int half = len / 2; // 擴張範圍的一半(如邊長 3,擴張距離是 1)
// half 有點像半徑的概念
// 邊界檢查
if (r - half < 0 || r + half >= M || c - half < 0 || c + half >= N)
return false;
// 檢查範圍內所有字元是否與中心相同
for (int i = r - half; i <= r + half; ++i) {
for (int j = c - half; j <= c + half; ++j) {
if (grid[i][j] != ch)
return false;
}
}
return true;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int M, N, Q;
cin >> M >> N >> Q;
cout << M << " " << N << " " << Q << "\n";
vector<string> grid(M);
for (int i = 0; i < M; ++i) {
cin >> grid[i];
}
while (Q--) {
int r, c;
cin >> r >> c;
int maxLen = 1; // 初始化最大正方形邊長為 1(最小可能)
// 擴張正方形邊長:從 3 開始每次加 2(保持為奇數)
for (int len = 3;; len += 2) {
if (is_valid(grid, r, c, len, M, N)) {
maxLen = len; // 若合法就更新最大長度
} else {
break; // 否則跳出迴圈,因為不能再擴張了
}
}
cout << maxLen << "\n";
}
}
return 0;
}
```
## 37. Satellites
Uva Online Judge:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1162
No Zerojudge :(
題目翻譯:
地球的半徑為 6440 公里。有許多的衛星和小行星圍繞著地球移動。如果兩個衛星與地心形成一個角度,你能求出它們之間的距離嗎?
在此,我們所說的距離是指「弧」長和「弦」長。兩者的衛星皆位於相同的軌道上。(然而,請考慮它們是在圓形軌道上旋轉,而非橢圓形軌道。)

**Input**
輸入檔將包含一個或多個測資。
每組測資含一行,由兩個整數 s、a 所組成,及一個字串 "min" or "deg"。
其中 s 表示衛星與與地球表面的距離,a 表示衛星與地心間的夾角,單位可能是 min 分(')或 deg 度(◦)。
請記得同一行永遠不會同時有分和度。
**Output**
對於每組測資,輸出一行,其中包含所需的距離,即兩顆衛星之間的弧長和弦長,以公里為單位。此距離應為浮點數值,顯示到小數點後六位數。
**Sample Input**
```
500 30 deg
700 60 min
200 45 deg
```
**Sample Output**
```
3633.775503 3592.408346
124.616509 124.614927
5215.043805 5082.035982
```
解題思路:
1. 計算半徑
s 為衛星到地球表面的距離,而題目有給地球半徑 = 6440 km,因此可算由衛星到地心的總半徑:
`r = R + s`,設地球半徑為 R = 6440 km。
2. 地心角單位換算
遇到 min 分的話,就除以 60 換算成 deg 度。
之後把度數轉成弧度,方便後續公式的計算:
```cpp
double rad = angle * π / 180;
```
3. 計算弧長
以下 θ 皆為弧度。
$arc = r × θ$
4. 計算弦長
$chord = 2 × r × sin(\frac{θ}{2})$
最後要說一下這題有陷阱阿,試了好幾次都 WA,才知道問題出在 a 大於 180 度的情形。
因為題目要求最短距離,所以超過 180 度的都要寫 `360 - a`。
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
const double R = 6440.0;
const double PI = acos(-1.0);
int main() {
double s, a;
string unit;
while (cin >> s >> a >> unit) {
double r = R + s;
if (unit == "min") {
a = a / 60.0;
}
if (a > 180.0) {
a = 360.0 - a;
}
double rad = a * PI / 180.0;
double arc = r * rad;
double chord = 2.0 * r * sin(rad / 2.0);
printf("%.6f %.6f\n", arc, chord);
}
return 0;
}
```
## 38. Can You Solve It?
PDF Source:https://onlinejudge.org/external/106/10642.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=i859
題目翻譯:
首先請看看下圖。在這張圖中,每個圓圈在笛卡兒座標系(就是直角坐標系)中都有一個座標。你可以沿著圖中標示的箭頭方向,從一個圓圈移動到另一個圓圈。若要從起始圓圈走到目標圓圈,
total_number_of_step(s)_needed = number_of_intermediate_circles_you_pass + 1
舉個例子,若要從 (0, 3) 走到 (3, 0),你必須經過兩個中間圓圈 (1, 2) 和 (2, 1)。因此,在這個例子中,總步數為 2 + 1 = 3。
於本題中,你的任務是計算從一個起始圓圈到一個目標圓圈所需的步數。你可以假設無法逆著箭頭方向返回。
精選單字:
- coordinate (n.) 座標
- (v.) 協調;使相配合
解題思路:
這題我想了很久,最後沒辦法只能上網找解題思路,沒想到居然是用公式解出來的!?
解題思路主要就是把所有座標依照 x + y 去做分層,每層由左下到右上(假設平面座標不是題目畫的那樣奇奇怪怪的,而是 x 軸為橫軸、y 軸為縱軸)去做一個編號:
| 座標 (x, y) | 序號 idx |
| --------- | ------ |
| (0,0) | 0 |
| (0,1) | 1 |
| (1,0) | 2 |
| (0,2) | 3 |
| (1,1) | 4 |
| (2,0) | 5 |
| … | … |
而分層的意思是依照平面上所有座標的 x + y 值去做分類,如果 x + y 值相同就會被分到同一層。
也可以想成是題目給的圖中,往左上的斜線經過的點都是同一層(原點 (0, 0) 也被視為一層)。

那可以從表中觀察到幾個規律:
- 每層的每點皆滿足 x + y = n 的條件。(n 為每層中的一個定值,如第一層 0 + 0 = 0、第二層 1 + 0 = 1、0 + 1 = 1)
- 每層會有 n + 1 個點。
- 每層的初始編號為 $S = \frac{n(n+1)}{2}$ 。
另外 S 也表示在進入該層(即 $x + y$ 層)之前,共有這麼多個點。(如 n = 2,進入點 (0, 2) 之前有三個點 (0, 1), (1, 0), (0, 0))
經過多次驗證跟思考,如果在 S 後面加上一個 x,就可以推算出座標點的編號了。
舉個栗子:
$(1, 1)$ 的 n = 2,S = 3,編號 = 3 + 1 = 4。
$(1, 2)$ 的 n = 3,S = 6,編號 = 6 + 1 = 7。
看圖的話,編號上就結果而言是正確的,如果是 y 的話就變成:
- 3 + 1 = 4
- 6 + 2 = 8
雖然第一個是對的,但第二個編號錯了,因此不能 + y。
最後可得公式 $loc(x, y) = \frac{n(n+1)}{2} + x$ 。
由於只能向前,而不能向後移動,所以假設兩點 $(x1, y1), (x2, y2)$ ,則:
$step = loc(x2, y2) - loc(x1, y1)$
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll loc(ll x, ll y) {
ll n = x + y;
return n * (n + 1) / 2 + x;
}
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int T;
cin >> T;
for(int i = 1; i <= T; ++i) {
ll x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
ll ans = loc(x2, y2) - loc(x1, y1);
cout << "Case " << i << ": " << ans << '\n';
}
return 0;
}
```
## 39. Fourth Point!!
PDF Source:https://onlinejudge.org/external/102/10242.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=e512
題目翻譯:
已知平行四邊形兩條相鄰邊端點的 $(x, y)$ 座標。求第四個點的 $(x, y)$ 座標。
精選單字:
- adjacent (adj.) 鄰近的
- parallelogram (n.) 平行四邊形
解題思路:
利用向量及平行四邊形的性質去求第四個點。
平行四邊形的特性為對邊平行且長度相等。

用平行四邊形性質,可得到表示式: $\overrightarrow{AB} = \overrightarrow{CD}$ 。
假設 $A(0, 1), B(1, 1), C(0, 0), D(x, y)$ ,
$\overrightarrow{AB} = (1 - 0, 1 - 1) = B - A$
$\overrightarrow{CD} = (x - 0, y - 0) = D - C$
最後可得: $D - C = B - A$ → $D = C + (B - A)$ → $D = (1, 0)$ 。
記得題目的範例輸入不一定都是第二個、第三個點相同,所以這部分要一個一個找。
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
struct Point {
double x, y;
bool operator==(const Point& other) const { // overloading operator
return abs(x - other.x) < 1e-8 && abs(y - other.y) < 1e-8;
}
};
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
Point p[4];
while (cin >> p[0].x >> p[0].y >> p[1].x >> p[1].y >> p[2].x >> p[2].y >> p[3].x >> p[3].y) {
Point A, B, C;
if (p[0] == p[2]) {
A = p[0];
B = p[1];
C = p[3];
} else if (p[0] == p[3]) {
A = p[0];
B = p[1];
C = p[2];
} else if (p[1] == p[2]) {
A = p[1];
B = p[0];
C = p[3];
} else {
A = p[1];
B = p[0];
C = p[2];
}
double Dx = B.x + C.x - A.x;
double Dy = B.y + C.y - A.y;
// or printf("%.3f %.3f", Dx, Dy);
cout << fixed << setprecision(3) << Dx << " " << Dy << "\n";
}
return 0;
}
```
## 40. A mid-summer night’s dream
PDF Source:https://onlinejudge.org/external/100/10057.pdf
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=e606
題目翻譯:
今為公元 2200 年。科學在兩百年間進步了許多。提到兩百年是因為這個問題是利用時間機器送回到公元 2000 年。現在可以建立人與電腦 CPU 之間的直接連結。人們可以透過 3D 顯示器(也就是今天的螢幕)來觀看他人的夢境,就像看電影一樣。本世紀的一個問題是人們對電腦變得過度依賴,以致於他們的分析能力幾乎接近於零。電腦現在可以閱讀問題並自動解決它們,但只能解決困難的問題。現在沒有簡單的問題了。我們的首席科學家遇到了大麻煩,因為他忘記了組合鎖的密碼。出於安全考量,現今的電腦無法解決和組合鎖相關的問題。在一個仲夏夜,科學家做了一個夢,夢見許多無號整數四處飛舞。他利用他的電腦記錄下這些數字,然後他得到線索,如果這些數字是( $X₁, X₂, ..., Xₙ$ ),他必須找到一個整數 $A$ ( $A$ 是組合鎖密碼),使得
$(|X₁ - A| + |X₂ - A| + ... + |Xₙ - A|)$
的值最小。
精選單字:
- as if 好像、彷彿
- chief (adj.) 首席的、首要的
解題思路:
這題的重點就是要找到一個 A 使 S 最小:
$S = \sum^n_{i = 1} |X_i - A|$
其實這題跟 Vito's family 蠻像的,A 是要取中位數,才可以讓 S 變最小。
為了方便求中位數,所以要先將資料排序。
若資料總量 n 是奇數,表示中位數只有一個,否則為兩個。
遇到兩個中位數可這樣求:
```cpp
int low = v[n / 2 - 1];
int high = v[n / 2];
```
若要計算輸出的第二個數字(`|Xi − A|` 為最小值的數量,其實就是找兩個中位數間的區間長),則用:
```cpp
int count = upper_bound(v.begin(), v.end(), high) - lower_bound(v.begin(), v.end(), low);
```
用線性搜尋找也不是不行,但既然都資料排序了,那用二分搜豈不是更快?
第三個數字則是算區間長度:
```cpp
int range_count = high - low + 1;
```
範例程式碼:
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;
while (cin >> n && n > 0) {
vector<int> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i];
}
sort(v.begin(), v.end());
if (n % 2 == 1) {
int median = v[n / 2];
int count = upper_bound(v.begin(), v.end(), median) - lower_bound(v.begin(), v.end(), median);
cout << median << " " << count << " 1\n";
} else {
int low = v[n / 2 - 1];
int high = v[n / 2];
int count = upper_bound(v.begin(), v.end(), high) - lower_bound(v.begin(), v.end(), low);
int range_count = high - low + 1;
cout << low << " " << count << " " << range_count << "\n";
}
}
return 0;
}
```