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

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

T1 打渔还是晒网

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

解题思路:

数学题。可以发现周期是 \(5\) 天,所以判断 \(n\) 除以 \(5\) 的余数是不是 \(1,2,3\) 即可。实际解决时我是使用 (n-1)%5<3 来判断的。

示例程序:

#include <bits/stdc++.h>
using namespace std;
int n;
int main() {
    cin >> n;
    puts((n-1)%5 < 3 ? "Fishing" : "Lying");
}

T2 数字加密

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

解题思路:

简单字符串模拟题。按照题目的反过程还原原来的字符串即可。

示例程序:

#include <bits/stdc++.h>
using namespace std;
char s[5];
void t(char &c) {
    int a = c - '0';
    c = '0' + 9 - a;
}
int main() {
    cin >> s;
    for (int i = 0; i < 4; i ++) t(s[i]);
    for (int i = 0; i < 2; i ++) swap(s[i], s[3-i]);
    puts(s);
    return 0;
}

T3 双质数

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

解题思路:

函数+循环。考查函数的应该和循环。注意:判断素数得用 \(O(\sqrt a)\) 的方法,或者使用素数筛法。

示例程序1(\(O(\sqrt a)\) 判素数):

#include <bits/stdc++.h>
using namespace std;
bool check(int a) {
    if (a < 2) return false;
    for (int i = 2; i*i <= a; i ++)
        if (a % i == 0)
            return false;
    return true;
}
int a, b;
bool flag;
int main() {
    cin >> a >> b;
    for (int i = a; i <= b; i ++) {
        if (check(i) && check(i/10)) {
            flag = true;
            cout << i << endl;
        }
    }
    if (!flag)
        puts("None");
    return 0;
}

示例程序2(素数筛法):

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int a, b;
bool flag, f[maxn];
void init() {
    f[0] = f[1] = true;
    for (int i = 2; i < maxn; i ++)
        if (!f[i])
            for (int j = i+i; j < maxn; j += i)
                f[j] = true;
}
int main() {
    init();
    cin >> a >> b;
    for (int i = a; i <= b; i ++) {
        if (!f[i] && !f[i/10]) {
            flag = true;
            cout << i << endl;
        }
    }
    if (!flag)
        puts("None");
    return 0;
}

T4 连乘问题

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

解题思路:

方法1: 动态规划 递推,求解前缀和后缀。\(f[i]\) 表示前 \(i\) 个数的乘积 \(\mod 10000\) 的结果。\(g[i]\) 表示 \(a_i\)\(a_n\) 的成绩 \(\mod 10000\) 的结果。

方法2:扩展GCD求解矩阵的逆。

示例程序(方法1):

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, a[maxn], f[maxn], g[maxn];
const int MOD = 10000;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    f[0] = 1;
    for (int i = 1; i <= n; i ++) f[i] = f[i-1] * a[i] % MOD;
    g[n+1] = 1;
    for (int i = n; i >= 1; i --) g[i] = g[i+1] * a[i] % MOD;
    for (int i = 1; i <= n; i ++)
        cout << f[i-1] * g[i+1] % MOD << endl;
    return 0;
}

T5 救援争先

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

解题思路:

结构体排序。稍微要注意一下处理输入格式。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
struct Node {
    int sh, sm, st, dh, dm, et, id;
} a[maxn];
bool cmp(Node a, Node b) {
    return a.et<b.et || a.et==b.et && a.st<b.st || a.et==b.et && a.st==b.st && a.id<b.id;
}
int n;
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++) {
        scanf("%d:%d %d:%d", &a[i].sh, &a[i].sm, &a[i].dh, &a[i].dm);
        a[i].st = a[i].sh * 60 + a[i].sm;
        a[i].et = a[i].st + a[i].dh * 60 + a[i].dm;
        a[i].id = i+1;
    }
    sort(a, a+n, cmp);
    for (int i = 0; i < n; i ++)
        printf("%d\n", a[i].id);
    return 0;
}
posted @ 2021-06-10 18:08  quanjun  阅读(1581)  评论(0编辑  收藏  举报