【個人筆記】C++ ZeroJudge 基礎題庫解題(純練習) - part 4
===
a022.:https://zerojudge.tw/ShowProblem?problemid=a022
難度:★☆☆☆☆
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main(){
bool re = true;
int count;
string input;
cin >> input;
count = input.size();
char result[count];
strcpy(result, input.c_str());
for (int i = 0; i < floor(count / 2); i++){
if (result[i] != result[count-1-i]){
re = false;
}
}
cout << (re ? "yes" : "no");
return 0;
}
```
這邊用到了 bool 資料型態,表示是不是迴文,預設為 true,也就是迴文的意思。
而 strcpy 的部分需要注意,務必將 input 的 string 型態轉為 char,使用到函數 `c_str()`。
而 for 迴圈裡面的 `floor(count / 2)` 表示向下取整,如果直接寫 `count / 2` 也是可以,但是會耗損較多時間。
for 下面的條件判斷就是判斷前半部分是否與後半部分相同,如果不同就將 re 設為 false。
最後三元運算子有個小細節,由於運算子優先順序的原因,`<<` 的優先級大於 `? :` 所以如果單純寫:`cout << re ? "yes" : "no";` 輸出只會有 1 跟 0。
因此最後輸出部分的三元運算子需要加上小括號。
a024.:https://zerojudge.tw/ShowProblem?problemid=a024
難度:★☆☆☆☆
內建函式庫寫法:
```cpp=
// C++ 14 寫法(因為zerojudge僅支援 C++ 14)
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int x, y;
cin >> x >> y;
cout << __gcd(x, y);
return 0;
}
```
輾轉相除法寫法(for迴圈):
```cpp=
#include <iostream>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int x, y, temp;
cin >> x >> y;
while (y != 0) { // (a, b) = (b, a % b)
temp = y;
y = x % y;
x = temp;
}
cout << x;
}
```
遞迴寫法:
```cpp=
#include <iostream>
using namespace std;
int gcd(int x, int y) {
if (x % y == 0) return y;
return gcd(y, x % y);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int x, y;
cin >> x >> y;
cout << gcd(x, y);
return 0;
}
```
a034.:https://zerojudge.tw/ShowProblem?problemid=a034
難度:★★☆☆☆
使用 bitset 容器解(比較難的是如何移除前導 0):
```cpp=
#include <iostream>
#include <bitset>
using namespace std;
int main() {
int decimal;
while (cin >> decimal){
bitset<32> binary(decimal);
string binary_str = binary.to_string();
// size_t 為 unsigned int
size_t first_one = binary_str.find('1'); // 找到第一個 1
// 以下判斷是移除前導 0 的步驟
if (first_one != string::npos) {
binary_str = binary_str.substr(first_one);
} else {
binary_str = "0";
}
cout << binary_str << "\n";
}
return 0;
}
```
:::info
`string::npos` 用在 `string.find()` 函數上,表示查找失敗,因為它通常被定義成 `static const size_t npos = -1;`。
:::
不用函式庫的寫法:
```cpp=
#include <iostream>
using namespace std;
void decimalToBinary(int n) {
if (n == 0) {
cout << "0";
return;
}
int binary[32];
int index = 0;
while (n > 0) {
binary[index] = n % 2;
n = n / 2;
index++;
}
for (int i = index - 1; i >= 0; i--) {
cout << binary[i];
}
cout << "\n";
}
int main() {
int decimal;
while(cin >> decimal){
decimalToBinary(decimal);
}
return 0;
}
```
a038.:https://zerojudge.tw/ShowProblem?problemid=a038
難度:★★☆☆☆
```cpp=
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
if (n == 0) {
cout << 0;
return 0; // 加上 return 0; 使程式提前結束
}
int reversed = 0;
while (n != 0) {
int digit = n % 10;
reversed = reversed * 10 + digit;
n /= 10;
}
cout << reversed;
return 0;
}
```
程式碼說明:
1. `while` 的地方,每次取 `% 10`,一次拿最右邊的一位數字出來。
2. 把拿出來的數字,累積放到新的數字後面(乘 10,讓位置往左移)。
3. 原來的數字除以 10,把剛剛處理過的那一位刪掉。
4. 重複這個動作直到原數字變成 0。
如 12345:
1. 先把 5 拿出來。
2. reversed 經過計算後等於 5。
3. n 除以 10,變成 1234。
4. 接下來以此類推,再把最後的 4 拿出來,reversed 計算後變成 50 + 4 = 54。
a040.:https://zerojudge.tw/ShowProblem?problemid=a040
難度:★★☆☆☆
這是一道很經典的窮舉題目。
```cpp=
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
bool isArmstrong(int num) { // 判斷是否為阿姆斯壯數
int original = num; // 保留原始數字(比較用)
int sum = 0;
int digits = 0;
int temp = num;
while (temp > 0) { // 算有幾位數
digits++;
temp /= 10;
}
temp = num;
while (temp > 0) { // 計算每位數的 n 次方總和
int digit = temp % 10;
sum += pow(digit, digits);
temp /= 10;
}
return sum == original;
}
int main() {
int n, m;
cin >> n >> m;
vector<int> armstrongNumbers;
for (int i = n; i <= m; ++i) {
if (isArmstrong(i)) {
armstrongNumbers.push_back(i);
}
}
if (armstrongNumbers.empty()) {
cout << "none";
} else {
// size_t 就是 unsigned int
for (size_t i = 0; i < armstrongNumbers.size(); ++i) {
cout << armstrongNumbers[i];
if (i != armstrongNumbers.size() - 1) {
cout << " ";
}
}
}
return 0;
}
```