第三届里奇杯编程大赛(初赛)题解

A.签到

签到题,直接输出即可。

#include <bits/stdc++.h>
using namespace std;

int main()
{
	cout << "Hello Liqi contest";
	return 0;
}

B.挂科

读取到每个人的成绩后,判断符合挂科条件(分数$ < p$ )就 \(res\) 增加一位同学 。

#include <iostream>
#include <algorithm>

using namespace std;

const int N =  1e5+10;
int n, p, a[N], res;

int main() {
    scanf("%d%d", &n, &p);
    for(int i=1; i<=n; i++) {
        scanf("%d", &a[i]);
        if(a[i] < p) res++;
    }
    printf("%d\n", res);
    return 0;
}

C.送外卖

经过论证,可以发现,沿着坐标轴,从左到右一口气送完外卖是最佳方案。

故将求出 \(a\) 的最大值与最小值后直接相减即可。

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>

#define fi first
#define se second

using namespace std;
using ll = long long;
using pii = pair<int, int>;

const double eps = 1e-4;
const int N = 110;
int n;

void solve() {
    scanf("%d", &n);
    int minv = 1e9, maxv = 0;
    for(int i=1; i<=n; i++) {
        int x; scanf("%d", &x);
        minv = min(minv, x);
        maxv = max(maxv, x);
    }
    printf("%d\n", maxv-minv);
}

int main() {
    // multiple case
    // int t; scanf("%d", &t);
    // while(t--) {
    //     solve();
    // }

    // single case
    solve();

    return 0;
}

D.分弹珠

每个弹珠都一模一样,故弹珠分配方案的不同只有每个人分的的弹珠多少。

每个人能分得的弹珠数量区间是 \([1, n-1]\) ,故方案数为 \(n-1\) 。这里直接把弹珠数量为 \(1\) 的情况(没有合理的分配方案)也涵盖了。

#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
	cin >> n;
	cout << n - 1;
	return 0;
}

E.加倍整数

比起判断某个数是否为加倍整数,不如直接构造加倍整数出来,判断他与 \(n\) 的关系。

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>

#define fi first
#define se second

using namespace std;
using ll = long long;
using pii = pair<int, int>;

const double eps = 1e-4;
const int N = 1e6+10;
ll n;

// 将x变为xx的加倍整数
inline ll bianshen(ll x) {
    string s = to_string(x);
    s = s + s;
    return stoll(s);
}

void solve() {
    cin >> n;
    ll res = 0;
    for(ll i = 1; i < N; i++) {
        ll x = bianshen(i);
        if(x <= n) res++;
    }
    cout << res << endl;
}

int main() {
    // multiple case
    // int t; scanf("%d", &t);
    // while(t--) {
    //     solve();
    // }

    // single case
    solve();

    return 0;
}

F.大学生特种兵

假如有一段路程为 \(1->2->4->5->3\),则他旅行的起点可以为其中的任意一个,终点为起点后的任意一个。故我们可以枚举起点,然后搜索他能够去到哪些终点。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>

using namespace std;
const int N = 2010;
int n, m, st[N];
vector<int> e[N];

// 任何dfs的u都可能为终点
void dfs(int u, int &sum) {
    st[u] = true;
    sum++;
    for(auto ne:e[u]) {
        if(st[ne]) continue;
        dfs(ne, sum);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i=1; i<=m; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        e[a].push_back(b);
    }
    int res = 0;
    for(int i=1; i<=n; i++) {
        memset(st, 0, sizeof(st));
		// 这里的表示起点为i
        dfs(i, res);
    }
    printf("%d\n", res);
    return 0;
}

G(Ex).不许6

\(a = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, ...]\)。从这里可以发现这个数字世界就是一个使用数字 \(0, 1, 2, 3, 4, 5, 7, 8, 9\) 的九进制。故我们将获取到的数字从十进制转换为九进制即可,注意把转换后的 \([6, 8]\) 变为 \([7,9]\)

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
using ll = long long;

void solve() {
    ll k; scanf("%lld", &k);
    vector<ll> res;
    while(k) {
        res.push_back(k%9);
        k /= 9;
    }
    reverse(res.begin(), res.end());
    for(auto &x:res) {
        if(x >= 6) x++;
        printf("%lld", x);
    }
    puts("");
}

int main() {
    int t; scanf("%d", &t);
    while(t--) {
        solve();
    }
    return 0;
}
posted @ 2023-05-27 19:19  1v7w  阅读(163)  评论(0编辑  收藏  举报