A - Long Loong
输入一个正整数 nnn,输出一个字符串:‘L’ + nnn 个 ‘o’ + ‘n’ + ‘g’。
解:
#include <bits/stdc++.h>
using namespace std;
int main() {
long long a;
cin >> a;
printf("L");
for (int i = 0; i < a; i++)
printf("o");
printf("ng\n");
return 0;
}
B - CTZ
输入一个数正整数 nnn, 输出这个数的二进制表示中有多少个后缀 ‘0’。
解:
#include <bits/stdc++.h>
using namespace std;
int main() {
long long a;
cin >> a;
long long ans = 0;
while (a) {
if (a % 2 == 0) {
ans++;
a /= 2;
}
else break;
}
printf("%lld\n", ans);
return 0;
}
C - Even Digits
输入一个正整数 nnn,输出在(0,2,4,6,8,20,22,24,26,28,40,…)进制下第 nnn 个数是多少。从 000 开始计数。
解:
只需将 0, 1, 2, 3, 4替换成 0, 2, 4, 6, 8。
#include <bits/stdc++.h>
using namespace std;
int q[100], idx;
int main() {
long long a;
cin >> a;
a--;//从0开始计数,所以先减去1
long long ans = 0;
if (!a) printf("0");// 再特判
while (a) {
q[++idx] = (a % 5) * 2;
a /= 5;
}
for (int i = idx; i >= 1; i--)
printf("%d", q[i]);
return 0;
}
D - Pyramid
输入一个正整数数 nnn 和 nnn 个正整数,只能进行以下两种操作,操作次数不限:
1、 删除第一个数或者删除最后一个数。
2、 将一个位置的数减 1。
问能构成的最高的金字塔型有多高。
金字塔型即:1、1 2 1、1 2 3 2 1、1 2 3 4 3 2 1,高度分别是 1,2,3,4。
解:
动态规划的思想,先考虑左半部分,假设循环枚举到第 iii 个位置,如果前面一个位置能达到的高度为 mmm,则当前位置能达到的最高高度为 min(a[i],m+1)min(a[i], m + 1)min(a[i],m+1)。因为:
1、如果前面一个位置能达到的最高高度大于第 iii 个位置的数 a[i]a[i]a[i],那么当前最大高度只能达到 a[i]a[i]a[i] 。因为只减不加,所以最大高度为 a[i]a[i]a[i];再者可以通过将前面的数全部减 111 使得前面的数减小到 a[i] - 1,使得 a[i]a[i]a[i] 这个高度能达到。
2、如果当前位置比前面一个位置能达到的最高高度大,由于要维持金字塔型,前面的最大高度为 mmm,所以只能将当前的数变为 m+1m+1m+1 来达到最大高度。
综上即是 min(a[i],m+1)min(a[i], m + 1)min(a[i],m+1) 的由来。
同理再考虑金字塔的右半部分,可得出第 iii 个位置左半部分和右半部分能达到的最大高度,设为 l[i],r[i]l[i], r[i]l[i],r[i],则以当前第 iii 个位置为塔尖的金字塔最大高度为 min(l[i],r[i])min(l[i], r[i])min(l[i],r[i])。枚举每一个位置作为塔尖,即可得出答案。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N], n;
int l[N], r[N];
int ans;
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
l[i] = min(a[i], l[i-1] + 1);
for (int i = n; i >= 1; i--)
r[i] = min(a[i], r[i+1] + 1);
for (int i = 1; i <= n; i++)
ans = max(ans, min(l[i], r[i]));
printf("%d\n", ans);
return 0;
}
拓展:
可以为题目进行拓展,比如将操作 111 改成可以删除任一位置的数;达到最大高度的同时将操作数降到最少。
//修改操作 1
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N], n;
int l[N], r[N];
int q[N], tt;
int ans;
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) {
while (tt && a[q[tt]] >= a[i]) tt--;
if (tt) l[i] = l[q[tt]] + min(i - q[tt], a[i] - a[q[tt]]);
else l[i] = min(a[i], i);
q[++tt] = i;
}
tt = 0;
for (int i = n; i >= 1; i--) {
while (tt && a[q[tt]] >= a[i]) tt--;
if (tt) r[i] = r[q[tt]] + min(q[tt] - i, a[i] - a[q[tt]]);
else r[i] = min(a[i], n - i + 1);
q[++tt] = i;
}
for (int i = 1; i <= n; i++)
ans = max(ans, min(l[i], r[i]));
printf("%d\n", ans);
return 0;
}
文章介绍了四个编程问题:按给定规则生成特定字符串,计算二进制中后缀零的数量,将数字转换为特定进制,以及构建金字塔型的最大高度。每个问题都涉及不同的算法和逻辑,如循环、条件判断和动态规划。

被折叠的 条评论
为什么被折叠?



