1.1623 大乐透
直接判断。
#include<cstdio>
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < 5; ++i) {
int m;
scanf("%d", &m);
if (m == n) {
puts("YES");
return 0;
}
}
puts("NO");
}
2.1627 欢乐的秋游
用mount数组存点,枚举除了边界的所有点,若mount[i] < mount[i - 1] 且mount[i] < mount[i + 1],则mount[i]一定是山谷,此外需要特殊处理一下mount[i] == mount[i + 1]的情况,详见代码。
#include<cstdio>
int mount[1005];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &mount[i]);
}
int ans = 0;
for (int i = 1; i < n - 1; ++i) {
if (mount[i] < mount[i - 1] && mount[i] < mount[i + 1]) {
++ans;
}
else if (mount[i] == mount[i + 1]) {
if (mount[i] < mount[i - 1]) {
int j = i + 1;
while (j < n && mount[i] == mount[j]) {
++j;
}
i = j - 1;
if (i < n && mount[i] < mount[i + 1]) {
++ ans;
}
}
}
}
printf("%d", ans);
}
3.1631 耗能的防雨罩
区间合并问题。对于区间[x1,y1],[x2,y2] 且 (x2 >= x1),定义right表示当前合并区间的最右端点,初始化right2 = y1,考虑以下几种情况。
情况一:两区间相离(x2 > right)。此时无法合并区间,答案+1,继续考虑后续区间。
情况二:两区间相交(x2 <= right)。此时可以合并区间,合并之后继续考虑后续区间。
情况三:两区间包含(x2 <= right)。更新right的值为y2,合并之后继续考虑后续区间。
#include<cstdio>
int start[1005];
int end[1005];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d %d", &start[i], &end[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
int right = end[i];
++ans;
int j = i + 1;
for (; j < n; ++j) {
if (start[j] <= right) {
right = right < end[j] ? right : end[j];
}
else {
break;
}
}
i = j - 1;
}
printf("%d", ans);
}
4.1635 大乐透1
直接判断。
#include<cstdio>
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < 5; ++i) {
int m;
scanf("%d", &m);
}
for (int i = 0; i < 2; ++i) {
int m;
scanf("%d", &m);
if (m == n) {
puts("YES");
return 0;
}
}
puts("NO");
}
5.1639 好吃的棒棒糖
模拟。对n个盘子从左到右打包,每打包k个盘子就输出一次结果。注意每次打包的数量只能小于上一次打包的数量。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
int sum = 0, last = 0x3f3f3f3f, cnt = 0;
for (int i = 0; i < n; ++i) {
int now;
cin >> now;
now = min(last - 1, now);
if (!now)break;
sum += now;
++cnt;
if (cnt == k) {
cout << sum << endl;
sum = cnt = 0;
}
last = now;
}
if (sum)cout << sum << endl;
}
6.1643 好玩的跳棋
动态规划。定义dp[i]表示跳到i坐标的最短距离,有如下状态转移方程:
d
p
[
i
+
j
]
=
m
i
n
(
d
p
[
i
+
j
]
,
d
p
[
i
]
+
1
)
,
其
中
1
≤
j
≤
a
r
r
[
i
]
dp[i+j]=min(dp[i+j], dp[i]+1) ,其中1\leq j \leq arr[i]
dp[i+j]=min(dp[i+j],dp[i]+1),其中1≤j≤arr[i]
#include<cstdio>
#include<cstring>
int dp[10005];
int min(int a, int b) {
return a < b ? a : b;
}
int main() {
memset(dp, 0x3f, sizeof dp);
int n, m;
scanf("%d", &n);
dp[0] = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", &m);
for (int j = 1; j <= m; ++j) {
dp[i + j] = min(dp[i + j], dp[i] + 1);
}
}
printf("%d", (dp[n - 1] == 0x3f3f3f3f ? -1 : dp[n - 1]));
}