首页 > 其他分享 >AtCoder Beginner Contest 352题解

AtCoder Beginner Contest 352题解

时间:2024-05-05 17:55:06浏览次数:30  
标签:巨人 AtCoder 下标 int 题解 cin 352 ldots

AtCoder Beginner Contest 352

Time : 2024-05-04(Sat) 20:00 - 2024-05-04(Sat) 21:40

A AtCoder Line

问题陈述

AtCoder 铁路线有 $N$ 个车站,编号为 $1, 2, \ldots, N$ 。

在这条线路上,有趟进站列车从 $1$ 站出发,依次停靠 $2, 3, \ldots, N$ 站,有趟出站列车从 $N$ 站出发,依次停靠 $N - 1, N - 2, \ldots, 1$ 站。

Takahashi 即将从 $X$ 站前往 $Y$ 站,只需使用进站和出站列车中的一列。

求这趟列车在 $Z$ 站是否停车。

输入

输入内容由标准输入法提供,格式如下

N X Y Z

题解

题意为检查Z是否处于X与Y之间

需根据X与Y的大小来判断乘坐进站列车还是出站列车

void solve() {
    cin >> n >> x >> y >> z;
    if(x > y)swap(x, y);
    cout << (x <= z && z <= y ? "Yes" : "No") << endl;
}

B Typing

问题陈述

Takahashi尝试使用键盘输入由小写英文字母组成的字符串 $S$ 。

他在键入时只看键盘,不看屏幕。

每当他错误地输入一个不同的小写英文字母时,他就立即按下退格键。然而,退格键被破坏了,因此误键入的字母没有被删除,实际键入的字符串是 $T$ 。

他没有误按小写英文字母以外的任何键。

$T$ 中未被误输入的字符称为正确输入字符

确定正确键入的字符在 $T$ 中的位置。

题解

S为理想输入, T为实际输入

题意为在T与S的字符串匹配, 每次输入S在T中的下标

算法 : 双指针

void solve() {
    string s, t;
    cin >> s >> t;
    for(int i = 0, j = 0; i < t.size() ; i++) {
        if(s[j] == t[i])cout << i + 1 << " ", j++;
    }
}

C Standing On The Shoulders

问题陈述

有 $N$ 个巨人,他们的名字分别是 $1$ 到 $N$ 。当巨人 $i$ 站在地上时,他们的肩高是 $A_i$ ,头高是 $B_i$ 。

你可以选择 $(1, 2, \ldots, N)$ 的 $(P_1, P_2, \ldots, P_N)$ 排列组合,并根据以下规则堆叠 $N$ 个巨人:

  • 首先,将巨人 $P_1$ 放在地上。巨人 $P_1$ 的肩膀距离地面的高度为 $A_{P_1}$ ,头部距离地面的高度为 $B_{P_1}$ 。

  • 为了 $i = 1, 2, \ldots, N - 1$ 的顺序,把巨人 $P_{i + 1}$ 放在巨人 $P_i$ 的肩膀上。如果巨人 $P_i$ 的肩膀距离地面的高度是 $t$ ,那么巨人 $P_{i + 1}$ 的肩膀距离地面的高度就是 $t + A_{P_{i + 1}}$ ,他们的头距离地面的高度就是 $t + B_{P_{i + 1}}$ 。

求最上面的巨人 $P_N$ 的头部距离地面的最大可能高度。

题解

总高度为N个巨人的肩高和加上最上方巨人的头高-肩高

总高度最大即最上方巨人头肩高差最大

遍历得最大值即可, 记得开long long

void solve() {
    cin >> n;
    int sd, hd, mx = -1;
    for(int i = 0; i < n; i++) {
        cin >> sd >> hd;
        res += sd;
        mx = max(mx, hd - sd);
    }
    cout << res + mx << endl;
}

D

问题陈述

img

题解

题意有点绕人, 简单来说是在 1 ~ N 的排列中找到长度为 k 的下标集合, 使得该下标集合对应的排列集合排序后为k长度的连续序列(a , a + 1 , a + 2 ... a + k - 1), 找到满足该条件下标集合的极差的最小值

一开始半天没读明白题, 觉得答案有单调性决定用二分答案加上滑动窗口来做, 思路不会优化TLE了

看到jiangly大佬有一个很巧妙的做法, 下标和排列P都是1 ~ N, 可以使用数组一一对应存储

使用set维护一个 k 长度的滑动窗口, 遍历 a 来寻找最小值, 具体见代码注释

void solve() {
    cin >> n >> k;
    for(int i = 1; i <= n; i++) {
        cin >> t;
        p[t] = i; //存储下标
    }
    
    set<int> s;//set集合有序存储滑动窗口中的下标
    for(int i = 1; i <= n; i++) { //枚举整数a
        s.insert(p[i]);
        if(i > k)s.erase(p[i - k]); //滑动窗口
        if(i >= k)
            ans = min(ans, *s.rbegin() - *s.begin()); //维护最大下标
    }
    cout << ans;
}

E Clique Connect

问题陈述

img

题解

很裸的一道求最小生成树题

稠密图, 选用Kruskal算法来完成

题目给定边的时候, 由于边权相等, 可以把给定集合看作一整个连通块, 便只相当于插入了k-1条边

int n, m, k, c, a, root, cnt;
int ans;
int p[N];//并查集维护节点的父节点

struct E {
    int a, b, c;
    bool operator < (const E& C) {
        return c < C.c;
    }
} edgs[N * 2];

int find(int u) {
    if(u != p[u])p[u] = find(p[u]);
    return p[u];
}

int kruskal() {
    for(int i = 1; i <= n; i++)p[i] = i;//初始化
    int num = 0;//存储最小生成树边的数目
    sort(edgs, edgs + cnt);
    for(int i = 0; i < cnt; i++) { //枚举edgs
        int a = edgs[i].a, b = edgs[i].b, c = edgs[i].c;
        if(find(a) != find(b)) { //如果两个节点没有联通(所在连通块根节点不同)
            p[find(a)] = find(b);
            ans += c;
            num++;
        }
    }
    return num;
}

void solve() {
    cin >> n >> m;
    while(m--) {
        cin >> k >> c;//题意即给定含有k个节点的连通块
        for(int i = 0; i < k; i++) {
            cin >> a;
            if(i > 0)
                edgs[cnt ++ ] = {root, a, c};//cnt为边的数量
            root = a;//以第一个节点为该连通块根节点
        }
    }
    if(kruskal() == n - 1)
        cout << ans << endl;
    else
        cout << -1 << endl;

}

F,G 等待更新...

标签:巨人,AtCoder,下标,int,题解,cin,352,ldots
From: https://www.cnblogs.com/l0tus/p/18173694

相关文章

  • P3193 [HNOI2008] GT考试 题解
    之前学矩阵乘的时候做的题,当时因为不会\(kmp\)搜索一稀里糊涂过去了,现在填个坑。头图是\(Logos\)!P3193[HNOI2008]GT考试题链:洛谷题库题目大意:求有多少个长度为\(n\)的数字串的子串中不包含给出的长度为\(m\)位的串,范围\(n<=1e9\),$m<=20$。思路:首先考虑DP,令\(......
  • CF1630A And Matching 题解
    题目描述有\(n\)个数\(0,1,2,\cdots,n-1\)。你需要把他们两两分组,使得每组两个数按位与的结果之和\(=k\)。如果可能,请构造出一组可能的\(\fracn2\)个数对,否则输出-1。保证\(n\)是\(2\)的幂,\(k\len-1\)思路首先我们发现,\(n\)是二的幂,所以按照二进制的角度看,这......
  • [SDOI2015] 星际战争 题解
    假如将所有激光武器放在一边,所有机器人放在一边,激光武器向它可以伤害的机器人连边,再加超级源/汇点,这就是一个网络流问题。考虑激光武器向机器人连的边容量无限,而机器人向超级汇点连的边容量为机器人的装甲值,而超级源点连向激光武器的边则是用时\(\times\)激光武器伤害。发现假......
  • CF729B Spotlights 题解
    题目简述给出一个$n$行$m$列的$01$矩阵,定义每个点的价值为上下左右四个方向有$1$的方向数,求所有为$0$的点的价值和。题目分析我们首先可以考虑暴力,但是发现是不行的。于是我们考虑动态规划。设$dp_{i,j,0/1/2/3}$分别表示$(i,j)$这个点上方,左方,下方,右方是否有$......
  • [SCOI2007] 蜥蜴 题解
    发现实际上就是在求有多少只蜥蜴能逃出来。发现可以将柱子拆成入点和出点两部分,自己的出点向别人的入点连边,自己的入点向自己的出点连边。最后再加一个超级源点\(S\),连接所有有蜥蜴的柱子入点;再加一个超级汇点\(T\),连接所有能够跳出地图的柱子。我们猛然发现:这个问题不就是求......
  • 题解:AT_abc352_C [ABC352C] Standing On The Shoulders
    考场憋了很久,最后代码贼短……理想状态下,直接全排列解决问题。但是,\(1\len\le2\times10^5\),明显TLE,试都不用试的。咋优化呢?其实,前面的巨人只负责“打地基”,作为“塔尖儿”的巨人有且仅有1个。而前面地基随便排列,地基高度(他们的和)都不会变。所以,我们只需要枚举塔尖即......
  • ABC352
    Alink\(x\)停不到,\(y\)能停到。要先判断是从前往后还是从后往前。点击查看代码#include<bits/stdc++.h>usingnamespacestd;signedmain(){ intn,x,y,z; cin>>n>>x>>y>>z; if(x<=y){ if(z>x&&z<=y)cout<<......
  • ABC352
    A.AtCoderLine判断\(z\)是否出现在\(x\)和\(y\)之间即可代码实现n,x,y,z=map(int,input().split())ifx>y:x,y=y,xifx<z<y:print('Yes')else:print('No')B.Typing模拟代码实现#include<bits/stdc++.h......
  • 牛客小白月赛92 题解
    牛客小白月赛92题解A.获得木头签到\((x\times4)/2\times4=x\times8\)#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.end()#defineendl'\n'#definedebug(x......
  • AtCoder Beginner Contest 352 考试总结
    前言正常发挥。属于是\(4\)个月没搞OI,复健成功了!得分明细:ABCDEFGTotal√√√√√××1475改题明细:ABCDEFG√√√√√××第一次正式rated打AT,行吧!A.AtCoderLineProblemAtCoder铁路线有\(N\)个车站,编号为\(1......