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 满足:
输入格式
第一行包含整数 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. 思路及题解
思路:
题解:
未完待续。。。