本文為2023年9月GESP C++四級的上機題目的詳細題解!覺得寫的不錯或者有幫助可以點個贊啦。
目錄
題目一講解視頻:
題目二講解視頻:
題目一:進制轉換
解題思路:
代碼(C++):
題目二:變長編碼
解題思路:
代碼(C++):
題目一講解視頻:
2023年9月GESP C++四級上機題一
題目二講解視頻:
2023年9月GESP C++四級上機題二
題目一:進制轉換
B3869 [GESP202309 四級] 進制轉換 - 洛谷
解題思路:
我們首先要理解進制的本質。
一個K進制數字,可以理解成逢K進一,也就是每滿K的時候往前進一位。
拿最熟悉的十進制數字舉例子,個位每滿10,十位數字就加一。
所以13可以表示為1?* 10 + 3, 34可以表示成3 * 10 + 4。
十位的數字要滿10的時候,就進一位, 百位數字加1,也就是百位數字x就相當于已經有x * 10 * 10了。
那么比如說,十進制的345也就可以表示成3 * 10 * 10 + 4 * 10 + 5。
這個同樣應用于任意進制的數字,所以對于一個K進制數字num
求它實際有多大,我們可以用它的第一位乘K的0次,第二位乘K的一次,第三位乘K的二次....最后加上總和,就是這個數字的大小。
這里就可以寫一個模擬的思路。
代碼(C++):
#include <bits/stdc++.h>
//https://blog.csdn.net/2401_83669813 csdn: @立志成為算法講師//0-9, 直接轉換成數字
//A-F, 跟'A'的差 + 10
int to10(char c) {if (c <= '9') {return c - '0';}return c - 'A' + 10;
}void solve() {int k;std::string numK;std::cin >> k >> numK;long long ans = 0;int p = 0;for (int i = numK.size() - 1; i >= 0; i--) {int num = to10(numK[i]);ans += (long long)num * std::pow(k, p);p++;}std::cout << ans << "\n";
}int main() {/*我們先要理解進制的本質一個K進制的數字,表示的是逢K進一十進制:0..9 10..19..八進制:0..7 10..17十進制23 = 2 * 10 + 3八進制23 = 2 * 8 + 3十進制的123 = 1 * 10 * 10 + 2 * 10 + 3八進制的123 = 1 * (8 ^ 2) + 2 * (8 ^ 1) + 3 * (8 ^ 0)*/int N;std::cin >> N;while (N--) {solve();}
}
題目二:變長編碼
B3870 [GESP202309 四級] 變長編碼 - 洛谷
解題思路:
首先來理解左移和右移操作。
對于一個數字n,n >> x,表示的是在n的二進制上整體向左移動,小于0的部分剔除掉。
比如101011 >> 3? => 101 (011),011小于0,直接剔除掉即可。那么最終結果是101。
在十進制上,n >> x可以看作n / (2 ^ x)。
反之就是往左移動。(視頻里面會有詳細的講解)
然后是與運算和或運算。
網址:Binary Fundamentals
如果有很多位的話,就是按照每一位進行分別進行位運算。
比如 3?& 6可以看成是:
0 1 1
1 1 0
變成 0 1 0
這個題目對一個數字二進制下,分成每組7位,那么我們可以與運算獲取這個數字的后7位,然后通過右移運算,讓這個數字的二進制每次減少7位。
對最高位進行操作的話,可以用或運算
具體可以看代碼和視頻解析!
代碼(C++):
#include <bits/stdc++.h>
//https://blog.csdn.net/2401_83669813 csdn: @立志成為算法講師char toChar(int num) {if (num < 10) {return num + '0';}return num - 10 + 'A';
}std::string to16(int num) {std::string res(2, '0');res[0] = toChar(num >> 4);res[1] = toChar(num & 15);return res;
}int main() {/*左移,右移運算n >> x與運算和或運算&,|1.不斷將數字右移7位,通過與運算獲取最后的7位數字2.對于在最高位添加1,可以通過或運算操作*/long long n;std::cin >> n;if (n == 0) {std::cout << "00";return 0;}//1.while (n > 0) {int num = n & 0x7F;//0111 1111n >>= 7;//2.if (n > 0) {//1000 0000num |= 0x80;}std::cout << to16(num) << " ";}
}