上海市计算机学会竞赛平台2020年4月月赛(丙组题目)题解

比赛链接:https://iai.sh.cn/contest/4

T1 竞选班长

题目链接:https://iai.sh.cn/problem/24

解题思路:

简单if条件判断。

示例程序:

#include <bits/stdc++.h>
using namespace std;
int a, b, c, d, e;
int main() {
    cin >> a >> b >> c >> d;
    if (a >= 90) e ++;
    if (b >= 90) e ++;
    if (c >= 90) e ++;
    puts(e >= 2 && d >= 85 ? "Qualified" : "Not qualified");
    return 0;
}

T2 永恒的生命游戏

题目链接:https://iai.sh.cn/problem/42

解题思路:

简单二维字符数组模拟。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int n, m;
char s[maxn][maxn];
bool in_map(int x, int y) {
    return x >= 0 && x < n && y >= 0 && y < m;
}
int cal(int x, int y) {
    int cnt = 0;
    for (int i = x-1; i <= x+1; i ++) {
        for (int j = y-1; j <= y+1; j ++) {
            if (i == x && j == y || !in_map(i, j)) continue;
            if (s[i][j] == '*') cnt ++;
        }
    }
    return cnt;
}
bool check(int x, int y) {
    int cnt = cal(x, y);
    return (s[x][y]=='*' && cnt>=2 && cnt<=3 || s[x][y]=='.' && cnt!=3);
}
bool solve() {
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++)
            if (!check(i, j))
                return false;
    return true;
}
int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i ++) cin >> s[i];
    puts(solve() ? "Still life" : "Other");
    return 0;
}

T3 直线运输

题目链接:https://iai.sh.cn/problem/33

解题思路:

递推,前缀和。设 (sum_i = sumlimits_{j=1}^i a_j),则答案为 (sumlimits_{i=1}^n sum_i)

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, a[maxn];
long long s, ans;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        s += a[i];
        ans += abs(s);
    }
    cout << ans << endl;
    return 0;
}

T4 数字验证

题目链接:https://iai.sh.cn/problem/26

解题思路:

字符串模拟。判断一个字符串是否是一个实数的合法表示。

示例程序:

#include <bits/stdc++.h>
using namespace std;
char s[505];
int main() {
    cin >> s;
    int p = 0;
    if (s[p] == '+' || s[p] == '-') p ++;
    int q = -1;
    int n = strlen(s+p);
    if (n == 1 && s[p] == '.') {
        puts("Invalid");
        return 0;
    }
    for (int i = p; s[i]; i ++) {
        if (s[i] == '.') {
            q = i;
            break;
        }
    }
    for (int i = p; s[i]; i ++) {
        if (i != q && !isdigit(s[i])) {
            puts("Invalid");
            return 0;
        }
    }
    puts("Valid");
    return 0;
}

T5 排队安排

题目链接:https://iai.sh.cn/problem/30

解题思路:

贪心。排序。模拟。
开一个变量 (c) 表示当前人数,如果 $ le a_i$,说明第 (i) 个人是保持在队列里面的。

注意:第 (i) 个人前面的人数不算他前面离开的人(只算还在的人)。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int n, a[maxn], c;

int main() {
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i];
    sort(a, a+n);
    for (int i = 0; i < n; i ++) {
        if (c <= a[i]) c ++;
    }
    cout << c << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/quanjun/p/14873162.html