跑步训练

图片说明

首先将跑1分钟和休息1分钟组合成一个轮次。每个轮次消耗300体力。

>>> 10000//300
33
>>> 10000%300
100

所以能完成33个轮次,也就是66分钟。

剩下的100体力 < 600体力。所以全部用于跑。

跑一分钟消耗600体力,所以一秒钟消耗10体力。

所以最后100体力能坚持10s。

>>> 66*60+10
3970

答:

上面的做法是错的。

必须预留一个轮次的空间,否则会出现现金流冻结。

先进行32个轮次,此时耗时64min,此时剩余400体力,全部用于跑,耗时40s。

答案是

纪念日

图片说明

首先考虑闰年的定义:4的倍数置闰,100的倍数不置闰,但400的倍数置闰。

cnt = 0
for i in range(1922, 2021):
    if i % 4 == 0: cnt += 1
print(cnt)
# 25

所以一共闰了

然后把时间切割成三段:

先计算中间段,一共是年。

然后计算前段,天。

然后计算后段,闰日不计,天。

故答案为分钟。

也可以把2020补给1921,这样1921的天数就是天。

那么答案就是分钟。

图片说明

合并检测

图片说明

首先模拟情况,100个人里有一个感染者。

第一轮需要个试剂盒,第二轮需要个试剂盒。

我想只对 100的因数考虑,因为如果不是因数就会出现浪费的情况,不知道这种想法有没有错。

其实主要是因为如果100不能整除k的话就要考虑平均期望,比较麻烦不太想算。

n = 100
ans = 100
tar = 1
for i in range(2, 51):
    if n % i: continue
    a = n / i
    cost = a + i
    if cost < ans:
        ans = cost
        tar = i
print(tar)

我的答案是10

提供一种均值不等式的解释:
第一轮需要个试剂盒,第二轮需要个试剂盒。
所以

REPEAT 程序

图片说明

比想象中的容易写。

说句实话一开始没看清楚单个缩进是4个空格 ,花了点时间debug。如果比赛可能会考虑替换成py,如果可以的话。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
int GetLevel(string s) {
    if (s.substr(0, 12) == "            ") return 3;
    if (s.substr(0, 8) == "        ") return 2;
    if (s.substr(0, 4) == "    ") return 1;
    return 0;
}
int main() {
    freopen("prog.txt", "r", stdin);//删掉文件里第一行A=0
    string s;
    int cir[5] = {0}, p = 0;//栈
    int last = -1;
    ll ans = 0;
    while (getline(cin, s)) {
        int now = GetLevel(s);
        if (now < last) p -= (last - now);//游标控制栈深
        last = now;
        if (s.substr(4 * now, 6) == "REPEAT")  cir[p++] = (s[s.length()-2] - '0');
        else {
            ll f = 1;//循环次数
            for (int i = 0; i < p; ++i) f *= cir[i];
            ll x = s[s.length() - 1] - '0';
            ans += f * x;
        }
    }
    cout << ans << endl;
    return 0;
}

运行结果是

矩阵

图片说明

可以将该问题转化为括号匹配:第一行存储左括号位置,第二行存储右括号位置。

的矩阵为例。

图片说明

即求

a = [0,1]
for i in range(1, 2021):
    a.append(a[i] * (2 * i + 1) * 2 // (i + 2))
print(a[1010]%2020)

整除序列

图片说明

#include <stdio.h>
#define sc(x) scanf("%lld", &(x))
#define pr(x) printf("%lld", (x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
int main() {
    ll n;
    while (~sc(n)) {
        while (n) {
            pr(n);
            n >>= 1;
            if (n) putchar(' ');
        }
        putchar('\n');
    }
    return 0;
}

解码

图片说明

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define sc(x) scanf("%s", (x))
#define pr(x) printf("%s", (x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
char s[105];
int main() {
    while (~sc(s)) {
        int n = strlen(s);
        for (int i = 0, j = 1; i < n; j = i + 1) {
            if (s[j] >= '0' && s[j] <= '9') {
                int x = s[j] - '0';
                while (x--) putchar(s[i]);
            } else putchar(s[i]);
            if (s[j] >= '0' && s[j] <= '9') i = j + 1;
            else i = j;
        }
        putchar('\n');
        memset(s, 0, sizeof(s));
    }
    return 0;
}

走方格

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define sc(x) scanf("%lld", &(x))
#define pr(x) printf("%d\n", (x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
ll n, m;
int main() {
    while (cin >> n >> m) {
        int dp[40][40] = {0};
        dp[2][1] = 1;
        for (int i = 2; i <= n; ++i) dp[i][1] = 1;
        for (int i = 2; i <= m; ++i) dp[1][i] = 1;
        for (int i = 2; i <= n; ++i) {
            for (int j = 2; j <= m; ++j) {
                if (i & 1 || j & 1) dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        pr(dp[n][m]);
    }
    return 0;
}

整数拼接

图片说明

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
ll n, k, a[N];
ll c[N][15];
int main() {
    while (~scanf("%lld%lld", &n, &k)) {
        memset(c, 0, sizeof(0));
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &a[i]);
            for (ll j = 1LL, p = 0; j <= 10000000000LL; j *= 10LL, ++p)
                ++c[a[i] * j % k][p];  // 10倍桶计数
        }
        ll ans = 0;
        for (int i = 1; i <= n; ++i) {
            ll len = log10(a[i]) + 1, r = a[i] % k, tmp = a[i];
            for (int i = 0; i < len; ++i) tmp *= 10LL;  //防止加自身
            if (r == 0 && c[r][len]) {//mod0 与mod0 匹配
                ans += (c[r][len]);
                if (tmp % k == 0) --ans;
            } else if (c[k - r][len]) {
                ans += c[k - r][len];
                if (tmp % k == k - r) --ans;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}  // 10 7 7 77 93 37 17 100 36 39 72 4

网络分析

图片说明
图片说明

还是只会写暴力

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define sc(x) scanf("%d", &(x))
#define pr(x) printf("%d", (x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
ll info[N];
int height[N];
int s[N];
int n;  // point numers
void init_set() {
    for (int i = 1; i <= n; ++i) s[i] = i, height[i] = 0;
    memset(info, 0, sizeof(info));
}
int find_set(int x) {
    if (x != s[x]) s[x] = find_set(s[x]);  //路径压缩
    return s[x];
}
void union_set(int x, int y) {
    x = find_set(x);
    y = find_set(y);
    if (height[x] == height[y])
        height[x] = height[x] + 1, s[y] = x;
    else if (height[x] < height[y])
        s[x] = y;
    else
        s[y] = x;
}
int m, op, a, b;
int main() {
    while (~sc(n)) {
        init_set();
        sc(m);
        for (int ca = 0; ca < m; ++ca) {
            sc(op);
            if (op == 1) {
                sc(a), sc(b);
                if (a != b) union_set(a, b);
            } else {
                sc(a), sc(b);
                int fa = find_set(a);
                for (int i = 1; i <= n; ++i) {
                    if (find_set(i) == fa) info[i] += b;
                }
            }
        }
        for (int i = 1; i <= n; ++i) pr(info[i]), putchar(i == n ? '\n' : ' ');
    }
    return 0;
}

不知道这样用set改会不会好一点。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <vector>
#define sc(x) scanf("%d", &(x))
#define pr(x) printf("%d", (x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
ll info[N];
set<int> team[N];
int height[N];
int s[N];
int n;  // point numers
int m, op, a, b;
void init_set() {
    for (int i = 1; i <= n; ++i)
        s[i] = i, height[i] = 0, team[i].insert(i), team[i].clear();
    memset(info, 0, sizeof(info));
}
int find_set_circle(int x) {
    int r = x;
    while (s[r] != r) r = s[r];  //找到根节点
    for (int i = x, j; i != r; i = j) {
        j = s[i], s[i] = r;  //把路径上的元素的集改为根节点
        team[r].insert(i);
    }
    return r;
}
void union_set(int x, int y) {
    x = find_set_circle(x);
    y = find_set_circle(y);
    s[y] = x, team[x].insert(y);
}
int main() {
    while (~sc(n)) {
        init_set();
        sc(m);
        for (int ca = 0; ca < m; ++ca) {
            sc(op);
            if (op == 1) {
                sc(a), sc(b);
                if (a != b) union_set(a, b);
            } else {
                sc(a), sc(b);
                int fa = find_set_circle(a);
                for (int x : team[fa]) info[x] += b;
            }
        }
        for (int i = 1; i <= n; ++i) pr(info[i]), putchar(i == n ? '\n' : ' ');
    }
    return 0;
}