廈門理工學院OJ 2020年期中機考題解
阿新 • • 發佈:2020-12-19
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]));
}