B - CTZ
难度: ⭐
题目大意
给定一个数n, 输出其二进制最后有几个连续的0;
解题思路
模拟一下就行;
神秘代码
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, idx;
signed main() {
IOS;
cin >> n;
while(n){
int x = n & 1;
if(x){
cout << idx;
break;
}
else idx++;
n >>= 1;
}
return 0;
}
C - Even Digits
难度: ⭐
题目大意
如果一个数的每个位都是偶数, 那么那个数就是好的; 请问第n个好数是多少;
解题思路
由题意得, 每个数都只能由0 2 4 6 8组成; 所以我们可以把好数看作是n的五进制表示; 由0 2 4 6 8 代替 0 1 2 3 4即可;
神秘代码
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, idx;
void solve(int u){
if(u < 5){
cout << 2 * u;
return;
}
solve(u / 5);
cout << 2 * (u % 5);
}
signed main() {
IOS;
cin >> n;
solve(n - 1);
return 0;
}
D - Pyramid
难度: ⭐⭐⭐
题目大意
我们定义1, 2... n - 1, n, n - 1 ...2, 1为n位金字塔数; 现在给定n个数, 可以对其进行任意次以下种操作, 问最多能得到几位金字塔数;
1- 选择其中一个数减一
2- 删除第一个数或者最后一个数
解题思路
简单分析后发现这个题与其从两边往中间找, 不如确定金字塔数的中心来的方便; 我们可以用dp来找出从左往右以第i个数结尾的金字塔数左侧的序列长度; 如果p[i]是金字塔数左侧第j个数, 那么只要p[i] >= j就可以; 所以只要p[i] > dp1[i - 1]那么就可以接在后面, 否则就只能开一个新的金字塔数, 并且长度就是p[i]; 从右往左也是同理;
对于以第i个数为中心的金字塔数的长度就是dp1和dp2的较小者; 遍历n个数找出最大值即可;
神秘代码
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, res;
int p[N];
int dp1[N], dp2[N];
signed main() {
IOS;
cin >> n;
for(int i = 1; i <= n; i++) cin >> p[i];
for(int i = 1; i <= n; i++){
if(p[i] > dp1[i - 1]){
dp1[i] = dp1[i - 1] + 1;
}
else dp1[i] = p[i];
}
for(int i = n; i >= 1; i--){
if(p[i] > dp2[i + 1]){
dp2[i] = dp2[i + 1] + 1;
}
else dp2[i] = p[i];
}
for(int i = 1; i <= n; i++){
res = max(res, min(dp1[i], dp2[i]));
}
cout << res;
return 0;
}