【官方题解】StarryCoding 入门教育赛 2 | acm | 蓝桥杯 | 新手入门

比赛传送门:

本场比赛开始时题面存在一些问题,私密马赛!

A.池化【入门教育赛】

根据题目所给公式计算即可。

cpp 复制代码
#include "bits/stdc++.h"

signed main() {
	int t; std::cin >> t;
	while (t --) {
		int l, k, s, p; 
		std::cin >> l >> k >> s >> p;
		int ans = floor((l + 2 * p - k) / s) + 1;
		std::cout << ans << "\n";
	}
}

B. 牢e买黄金【入门教育赛】

枚举卖点 i i i,那么仅需找到数组 a a a的区间 1 , i − 1 1, i - 1 1,i−1的最小值,维护一个前缀最值即可。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9;
using ll = long long;
ll a[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	ll n, x;cin >> n >> x;
	for(int i = 1;i <= n;++ i)cin >> a[i];
	ll mi = a[1], ans = 0;
	for(int i = 1;i <= n; ++ i){
		ans = max(ans, a[i] - mi);
		mi = min(mi, a[i]);
	}
	cout << ans * x << '\n';
	return 0;
}

C.前缀序列【入门教育赛】

思维题,我们从右往左考虑,对于 i i i,若 a i a_i ai为负数,就直接将其取相反数就好了,至多 n n n次一定可以使得所有元素为非负整数,所以答案就是所有元素的绝对值之和。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9;
using ll = long long;
ll a[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	ll n;cin >> n;
	for(int i = 1;i <= n;++ i)cin >> a[i];
	ll ans = 0;
	for(int i = 1;i <= n; ++ i)ans += (a[i] < 0 ? -a[i] : a[i]);
	cout << ans << '\n';
	return 0;
}

D.相邻最大公约数【入门教育赛】

动态规划,定义状态 d p i j dpij dpij表示 a i a_i ai是否增加 x x x(若 j = 0 j=0 j=0则没加 x x x,反之则加了)的情况下区间 1 , i 1, i 1,i相邻 g c d gcd gcd之和。

d p i 0 dpi0 dpi0可以从 d p i − 1 0 dpi - 10 dpi−10和 d p i − 1 1 dpi - 11 dpi−11转移过来, d p i 1 dpi1 dpi1亦同。

状态转移方程请见代码,注意从 2 2 2开始转移。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const int N = 1e5 + 9;
ll dp[N][2], a[N];

ll gcd(ll a, ll b){
	return b == 0 ? a : gcd(b, a % b);
}

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	ll n, x;cin >> n >> x;
	for(int i = 1;i <= n; ++ i)cin >> a[i];
	for(int i = 2;i <= n; ++ i){
		dp[i][0] = max(dp[i - 1][0] + gcd(a[i - 1], a[i]), dp[i - 1][1] + gcd(a[i - 1] + x, a[i]));
		dp[i][1] = max(dp[i - 1][0] + gcd(a[i - 1], a[i] + x), dp[i - 1][1] + gcd(a[i - 1] + x, a[i] + x));
	}
	cout << max(dp[n][0], dp[n][1]) << '\n';
}

E.基环树【入门教育赛】

基环树找环模板题,可用dfs或拓扑排序完成。

dfs解法:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 9;
ll a[N], n;
vector<int> g[N];
bitset<N> vis;
stack<int> stk;
ll ans;

bool dfs(int x, int fa){
    vis[x] = true;
    stk.push(x);
    for(const auto &y : g[x]){
        if(y == fa)continue;
        if(vis[y]){
            while(stk.size()){
                int t = stk.top();stk.pop();
                ans += a[t];
                if(t == y)break;
            }
            return true;
        }
        if(dfs(y, x))return true;
    }
    stk.pop();
    return false;
}

int main()
{
    cin >> n;
    for(int i = 1;i <= n; ++ i)cin >> a[i];
    
    for(int i = 1;i <= n; ++ i){
        int x, y;cin >> x >> y;
        if(x == y){
            cout << a[x] << '\n';
            return 0;
        }
        g[x].push_back(y), g[y].push_back(x);
    }
    if(n <= 2){
        ll ans = 0;
        for(int i = 1;i <= n; ++ i)ans += a[i];
        cout << ans << '\n';
        return 0;
    }
    dfs(1, 0);
    cout << ans << '\n';

    return 0;
}

拓扑排序做法:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 9;
ll a[N], ind[N], n;
vector<int> g[N];

void topo(){
    queue<int> q;
    for(int i = 1;i <= n; ++ i){
        if(ind[i] == 1)q.push(i);
    }
    while(q.size()){
        int x = q.front();q.pop();
        for(const auto &y : g[x]){
            if(-- ind[y] == 1)q.push(y);
        }
    }
}

int main()
{
    cin >> n;
    for(int i = 1;i <= n; ++ i)cin >> a[i];
    set<pair<int, int> > st;
    for(int i = 1;i <= n; ++ i){
        int x, y;cin >> x >> y;
        if(x == y){
            cout << a[x] << '\n';
            return 0;
        }
        g[x].push_back(y), g[y].push_back(x);
        ind[x] ++, ind[y] ++;
    }

    if(n <= 2){
        ll ans = 0;
        for(int i = 1;i <= n; ++ i)ans += a[i];
        cout << ans << '\n';
        return 0;
    }

    topo();

    ll ans = 0;
    for(int i = 1;i <= n; ++ i)if(ind[i] == 2)ans += a[i];
    cout << ans << '\n';

    return 0;
}
相关推荐
叩码以求索3 小时前
浅谈:算法萌新如何高效刷题应对面试(一)
算法·面试·职场和发展
谙弆悕博士3 小时前
信息系统项目管理师教程(第4版)笔记——第 2 章 信息技术发展
笔记·职场和发展·软考高级·软考·高项·项目经理
wdfk_prog6 小时前
嵌入式面试真题第 13 题:单硬件 Timer 下的高精度多路软件定时器架构设计
c语言·开发语言·面试·职场和发展·嵌入式
龙虾PRO8 小时前
能源与股票量化核心差异,AI全链路落地实操手册
java·面试·职场和发展
wdfk_prog12 小时前
嵌入式面试真题第 12 题:资源受限长期运行系统的确定性内存管理与内存池架构设计
考研·面试·职场和发展
思-无-涯14 小时前
测试面试新趋势:工程思维成关键
人工智能·功能测试·测试工具·职场和发展·可用性测试
醇氧1 天前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
谙弆悕博士1 天前
系统集成项目管理工程师教程(第3版)笔记——第17章:法律法规和标准规范
笔记·职场和发展·学习方法·业界资讯·软考·法律·法规
imbackneverdie1 天前
知网官宣:禁止 AI 列为论文署名作者,标注 Gemini、DeepSeek 等 AI 为作者的稿件统一下架
大数据·人工智能·ai·职场和发展·aigc·科研·高校
测试老哥2 天前
接口自动化测试分层设计与实践总结
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试