题解 | #大连大学2023年11月程序设计竞赛(同步赛)#

加训时间!

https://ac.nowcoder.com/acm/contest/69510/A

41edaeda82ecedb8a1d7040217d8375.jpg

A.加训时间!

根据题意,求出数组的最大值x,再*n即可。(第二次每个人都需要补x道题)

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> a(n);
    for (int i = 0; i < n; i ++) {
        std::cin >> a[i];
    }
    std::cout << n * *std::max_element(a.begin(), a.end()) << "\n";
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

B.爆wa种子!

  1. 由于a >= 0,那么 抛物线的开口向上,最小值为(4 * a * c - b * b )/ 4 / a;
  2. 若a = 0,b != 0,则方程变为直线,因此最小值为负无穷
  3. 若a = 0,b = 0,则方程变成平行于x轴的直线

因此只有2才能取到负无穷

注意取最小值时不要忘记与3取min,赛时忘了这个条件狂WA┭┮﹏┭┮

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

std::string inf = "-1000000000";

void solve() {
    int n;
    std::cin >> n;

    std::cout << std::fixed << std::setprecision(9);

    double min = 1e18;
    

    double ans = 1e9;
    for (int i = 1; i <= n; i ++) {
        int a, b, c;
        std::cin >> a >> b >> c;

        if (a == 0 and b != 0) {
            std::cout << inf << "\n";
            return;
        } else {
            double y = (4 * a * c * 1.0 - b * b) / (4 * a);
            ans = std::min(ans,y);
        }
        ans = std::min(ans,c * 1.0);
    }   

    std::cout << std::fixed << std::setprecision(9) << ans << "\n";
    
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

C. 晚上不睡觉

输出a*b的错误答案即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int a, b;
    std::cin >> a >> b;

    std::cout << a + b << "\n";
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

D. 书生的负数

贪心思考,操作不会时数组和增大或减少,那么我们可以将前n - 1个数通过操作全部变为负数,然后判断最后一个是否为负数即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;

    int a = 0;
    for (int i = 1; i <= n; i ++) {
        int x;
        std::cin >> x;
        a += x;
    }
    a += n - 1;
    int c = n - 1;
    if (a < 0) {
        c ++;
    }
    std::cout << c << "\n";
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}


E.明天

字符串查找,使用string的API即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "yes\n";
#define no std::cout << "no\n";

void solve() {
    std::string s;
    std::cin >> s;

    std::string str = "tomorrow";

    if (s == str) {
        no
        return;
    }

    if (str.find(s) != -1) {
        yes
    } else {
        no
    }
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

F.跳棋

通过观察可以发现,只要有两个格子上都有棋子,并且棋子的左边后者右边有空位,那么棋子就可以跳到所有位置上.

分别进行前后遍历,判断是否有满足上述条件的棋子,若没有,则输出棋子的数量

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;

    std::string s;
    std::cin >> s;

    s = " " + s;

    for (int i = 1; i <= n - 1; i ++) {
        if (s[i] == 'X' and s[i + 1] == 'X') {
            std::cout << n << "\n";
            return;
        }
    }

    for (int i = n; i >= 2; i --) {
        if (s[i] == 'X' and s[i - 1] == 'X') {
            std::cout << n << "\n";
            return;
        }
    }
    std::cout << std::count(s.begin(), s.end(),'X') << "\n";

    

}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

G.河流管理

(刚开始写了个线段树丢上去了,后来发现是并查集O(∩_∩)O) 由于每一次打开挡板,都会将这之间的河流合并,所以用并查集进行祖先的修改即可。

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

struct DSU {
    std::vector<int> pre, f, v;//f -> number

    DSU(int n) : pre(n), f(n, 1), v(n + 1) { std::iota(pre.begin(), pre.end(), 0); }
    DSU(std::vector<i64> init) : DSU(init.size()) {
        for (int i = 0; i < init.size(); i ++) {
            f.push_back(init[i]);
        }
    }
    int find(int x) {
        while (x != pre[x]) x = pre[x] = pre[pre[x]];
        return x;
    }
    bool same(int x, int y) { return find(x) == find(y); }
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return false;
        f[y] += f[x];
        v[y] = std::max(v[y],v[x]);
        pre[x] = y;
        return true;
    }
    int size(int x) { return f[find(x)]; }
};
//DSU dsu(n + 1);

void solve() {
    int n, m;
    std::cin >> n >> m;

    DSU dsu(n + 1);
    for (int i = 1; i <= n; i ++) {
        std::cin >> dsu.v[i];
    }

    while (m -- ) {
        int op;
        std::cin >> op;
        if (op == 1) {
            int l, r;
            std::cin >> l >> r;

            for (int i = dsu.find(l); i < dsu.find(r); i ++) {
                dsu.merge(i,i + 1);
            }

        } else {
            int x;
            std::cin >> x;

            std::cout << dsu.v[dsu.find(x)] << "\n";
        }

    }
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

H. 冒险

以为是背包问题,实则不是

由于每次装进背包后体积会*2,所以我们先拿体积小的即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<int> a(n);
    for (int i = 0; i < n; i ++) {
        std::cin >> a[i];
    }
    std::sort(a.begin(), a.end());
    int v = 0,c = 0;
    for (int i = 0; i < n; i ++) {
        if (v * 2 + a[i] <= m) {
            v *= 2;
            v += a[i];
            c ++;
        }
    }
    std::cout << c << "\n";
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}


I. 妙wa种子!

跟之前写过的一道题很像 由于要划分k段,所以一定有一种方案,能把数组中前k大的数全部包含进去,所以直接取前k大值即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<int> a(n);
    for (int i = 0; i < n; i ++) {
        std::cin >> a[i];
    }
    std::sort(a.begin(), a.end(),std::greater());

    std::cout << std::accumulate(a.begin(), a.begin() + m,0ll) << "\n";

}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}


J. 货币系统

显然,只要a,b,c三者互质,即可凑出

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int a, b, c;
    std::cin >> a >> b >> c;

    int d = std::gcd(a,b);
    d = std::gcd(d,c);

    if (d == 1) {
        yes
    } else {
        no
    }
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

K.从南到北II

字符串的删除,模拟即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;

    if (n < 3) {
        std::cout << s << "\n";
        return;
    }

    if (n == 3) {
        if (s == "hui" or s == "hen") {
            s = " ";
        }
        std::cout << s << "\n";
        return;
    }

    std::string ans = "";
    int i;
    for (i = 0; i < n - 2; i ++) {
        if (s[i] == 'h' and s[i + 1] == 'u' and s[i + 2] == 'i') {
            i += 2;
            continue;
        }
        if (s[i] == 'h' and s[i + 1] == 'e' and s[i + 2] == 'n') {
            i += 2;
            continue;
        }
        ans += s[i];
    }
    if (i != n) {
        while (i < n) {
            ans += s[i];
            i ++;
        }
    }
    if (ans.size() == 0) {
        std::cout << " " << "\n";
        return;
    }
    
    std::cout << ans << "\n";

}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}


L. 选拔

排序

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<int> a(n + 1);
    std::vector<std::vector<int>> adj(n + 1);

    std::vector<int> v;
    for (int i = 1; i <= n; i ++) {
        int k;
        std::cin >> k;
        for (int j = 1; j <= k; j ++) {
            int x;
            std::cin >> x;
            adj[i].push_back(x);
        }
        std::sort(adj[i].begin(), adj[i].end(),std::greater());
        a[i] = adj[i][0];
    }

    std::sort(a.begin() + 1, a.end(),std::greater());

    if (m <= n) {
        std::cout << std::accumulate(a.begin() + 1, a.begin() + 1 + m,0ll);
    } else {
        int ans = std::accumulate(a.begin() + 1, a.end(),0ll);
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j < adj[i].size(); j ++) {
                v.push_back(adj[i][j]);
            }
        }        
        std::sort(v.begin(), v.end(),std::greater());
        m -= n;
        ans += std::accumulate(v.begin(), v.begin() + m,0ll);

        std::cout << ans << "\n";
    }

}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}


M.远方

只要没有>=x 的建筑即可

#include <bits/stdc++.h>

using i64 = long long;
using PII = std::pair<i64,i64>;
#define int i64
#define yes std::cout << "yes\n";
#define no std::cout << "no\n";

void solve() {
    int n, x;
    std::cin >> n >> x;

    bool ok = true;
    for (int i = 0; i < n; i ++) {
        int y;
        std::cin >> y;
        if (y >= x) {
            ok = false;
        }
    }
    if (ok) {
        yes
    } else {
        no
    }
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}


全部评论

相关推荐

11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
M_bao:简历排版换一下吧,第二个项目换了吧,咱门双非学历本来就不行还用这种项目太掉分了,300沟通一个要简历你打招呼也有问题。
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务