AcWing第21場周賽總結
3997. 整數冪
題目連結:
https://www.acwing.com/problem/content/4000/
1. 題目描述
給定兩個整數 k 和 l,請判斷是否存在一個整數 n,滿足 kn=l。
輸入格式
第一行包含整數 T,表示共有 T 組測試資料。
每組資料佔兩行,第一行包含整數 k,第二行包含整數 l。
輸出格式
每組資料輸出一行結果,如果存在 n,則輸出 YES
,否則輸出 NO
。
資料範圍
前三個測試點滿足,2≤k,l≤100。
所有測試點滿足,1≤T≤10,\(2≤k,l≤2^{31−1}\)。
輸入樣例:
2
5
25
3
8
輸出樣例:
YES
NO
2. 思路及題解
思路:
-
直接使用
樸素演算法(暴力法)
-
如果l不能整除k,說明不可能滿足\(k^{n}=l\),直接輸出
NO
即可。 -
否則,計算k的n次冪,直到\(k^{n}≥l\)
-
若\(k^{n}>l\),說明不滿足條件,輸出
NO
-
若\(k^{n}=l\),說明滿足條件,輸出
YES
-
-
題解:
#include <iostream> #include <map> #include <vector> #include <utility> #include <algorithm> #include <cmath> #include <string> using namespace std; typedef long long ll; int main() { ll T; ll k, l; cin >> T; while (T--) { cin >> k >> l; if (l % k != 0) { cout << "NO" << endl; continue; } ll sum = 1; while (sum < l) { sum *= k; if (sum == l) { cout << "YES" << endl; break; } } if (sum > l) cout << "NO" << endl; } return 0; }
3998. 變成1
題目連結:
https://www.acwing.com/problem/content/4001/
1. 題目描述
給定一個二進位制數 x,在它變為 1 之前,不斷對它進行如下操作:
- 如果 x 為奇數,則將 x 加 1。
- 如果 x 為偶數,則將 x 除以 2。
請問,多少次操作後,xx 會變為 11。
輸入格式
共一行,一個 01 字串,表示二進位制數 x。
輸出格式
一個整數,表示所需操作次數。
資料範圍
前六個測試點滿足,x 的位數不超過 11。
所有測試點滿足,x 的首位不為 0,且位數不超過 \(10^6\)。
輸入樣例1:
1
輸出樣例1:
0
輸入樣例2:
1001001
輸出樣例2:
12
輸入樣例3:
101110
輸出樣例3:
8
2. 思路及題解
思路:
- 由於x的位數整體不超過\(10^6\),即需要用
字串(string)
儲存 - 對於二進位制字串,如何判斷二進位制奇偶數?
- 看二進位制的最低位,如果最低位為0,二進位制位偶數;如果最低位為1,二進位制位偶數。
- 如何對二進位制數進行
加1
和除2
操作?加1
:從最低位開始,逢二進一。除2
:二進位制右移一位,對於二進位制陣列,即二進位制字串長度減1
即可。
題解:
#include <iostream>
#include <map>
#include <vector>
#include <utility>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int main()
{
string s;
cin >> s;
ll cnt = 0;
ll end = s.size();
while (end != 1)
{
cnt++;
// 判斷二進位制最低位,如果為0,說明為偶數;如果為1說明為奇數
// 若為偶數,x除以2,即二進位制數右移1位,轉化到字串上,就是end減1
// 若為奇數,x加1,即從最低位開始加,逢二進一
if (s[end - 1] == '0') end--;
else
{
for (int i = end - 1; i >= 0; --i)
{
if (s[i] - '0' + 1 > 1)
{
s[i] = '0';
}
else
{
s[i] = '1';
break;
}
}
}
}
// 判斷如果s[0]為0,說明前面逢二進一時候,此時需要再做一次除2操作,即操作次數需要加1
if (s[0] == '0')
cout << cnt + 1 << endl;
else
cout << cnt << endl;
return 0;
}
3999. 最大公約數
題目連結:
https://www.acwing.com/problem/content/description/4002/
1. 題目描述
給定兩個正整數 a,m,其中 a<m。
請你計算,有多少個小於 m 的非負整數 x 滿足:
\[gcd(a,m)=gcd(a+x,m) \]輸入格式
第一行包含整數 T,表示共有 T 組測試資料。
每組資料佔一行,包含兩個整數 a,m。
輸出格式
每組資料輸出一行結果,一個整數,表示滿足條件的非負整數 x 的個數。
資料範圍
前三個測試點滿足,1≤T≤10。
所有測試點滿足,1≤T≤50,\(1≤a<m≤10^{10}\)。
輸入樣例:
3
4 9
5 10
42 9999999967
輸出樣例:
6
1
9999999966
2. 思路及題解
思路:
題解:
未完待續。。。