AtCoder Beginner Contest 351 A-F题解

AtCoder ABC351 A-D题解 AtCoder ABC351题解 阅读详情

比赛链接:https://atcoder.jp/contests/abc351
比赛时间:2024 年 4 月 27 日 20:00-21:40

A题:The bottom of the ninth

标签:循环、模拟
题意:给定 A A A队 9 9 9局的得分和 B B B队 8 8 8局的得分。求 B B B队的第 9 9 9局要得多少分,才能总得分超过 A A A队。
题解:分别求出两队的总得分,如果 B B B队当前总得分已经超过 A A A队了,输出 0 0 0;否则输出相差的分数值 + 1 +1 +1(因为要超过)。
代码:

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

int main() {
    // A队和B队 分别的得分之和
    int sum1 = 0, sum2 = 0, x;
    for (int i = 1; i <= 9; i++) {
        cin >> x;
        sum1 += x;
    }
    for (int i = 1; i <= 8; i++) {
        cin >> x;
        sum2 += x;
    }
    if (sum2 > sum1) cout << 0;
    else cout << sum1 - sum2 + 1;
    return 0;
}

B题:Spot the Difference

标签:数组、循环
题意:给定 N N Nx N N N的二维字符数组 A A A和 B B B。有一个坐标位置的字符不同,输出那个位置。
题解:输入两个二维数组,然后遍历每一个位置,看看字符是否相同,不同就输出那个位置坐标即可。
代码:

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

char s1[105][105], s2[105][105];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
    cin >> s1[i][j];

    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
        cin >> s2[i][j];
        if (s1[i][j] != s2[i][j]) {
            cout << i << " " << j;
            return 0;
        }
    }
    return 0;
}

C题:Merge the balls

标签:栈
题意:给定 n n n个球,第 i i i个球的大小是 2 a i 2^{a_i} 2ai​。轮流将这 n n n个球加到一个序列中,一开始序列为空。每加一个球,如果序列的最后一个球和倒数第二个球大小相同,就将这两个球移除,然后加入一个新球,新球的大小是这两个球大小之和。不断地进行操作直到序列最后两个球不同或者序列中只有一个球了停止,然后再不断地加入球,直到这 n n n个球都被加入了。求最后序列中剩下的球的个数。
题解:我们分析下样例,比如以下这个样例:
7
2 1 1 3 5 3 3
加入到第 3 个球的时候,形成 2 1 1,最后两个相同了,删掉这两个,然后加入一个 2,形成 2 2;最后两个又相同了,删掉这两个,然后加入一个 3。
加入第 4 个球的时候,形成 3 3,最后两个相同了,删掉这两个,然后加入一个 4,形成 4。
加入第 5 个球,形成 4 5。
加入第 6、7 个球,形成 4 5 3 3,最后两个相同了,删掉最后两个,加入一个 4。
所以最后序列中剩下 4 5 4。
注意:题目中输入的是球的指数,如果两个球大小相同都是 2 a i 2^{a_i} 2ai​,那么相加就是 2 ∗ 2 a i = 2 a i + 1 2*2^{a_i}=2^{a_{i+1}} 2∗2ai​=2ai+1​。
我们可以通过 栈 模拟不断地将最后的两个拿出来,然后进行合并,塞一个新的放到栈中的这个流程,不断进行这个操作,直到最后球都放完了,最终输出栈的大小即可。
代码:

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

stack<int> s;
int n, x;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> x;
        s.push(x);
        while (s.size() >= 2) {
            int a = s.top(); s.pop();
            int b = s.top(); s.pop();
            if (a != b) {
                s.push(b);
                s.push(a);
                break;
            } else {
                s.push(a + 1);
            }
        }
    }
    cout << s.size() << endl;
    return 0;
}

D题:Grid and Magnet

标签:搜索
题意:给定一个 n n nx m m m的地图,地图中 # 表示不可以走,. 表示可以走。在此基础上加上一个限制,如果一个 . 周围上下左右中有一个位置有 #,就不能移动。求从 . 的地方走最多能到达的格子数。
题解:如果没有限制,就是普通的搜索了,暴力跑就好了。加上这个限制,如果我们像连通块一样,提前把某个格子跑到,并且因为 周围上下左右有一个#就不能移动,提前打上标记。后面其实从其他位置出发也能跑到这个格子,这个格子的计数就少了。
那如果我们跑每个点的时候,都对整张地图的 v i s vis vis 标记 m e m s e t memset memset 重置一下,那么总的时间复杂度又太大了。
这边可以引入一个类似标记第几个连通块的 i d id id,我们跑每个没有被标记的点,在跑的过程中发现如果能走到的下个点的 v i s vis vis标记和当前标记不一样,也让它跑下去,并打上当前 i d id id,这样就能统计到所有能够跑到的点。
代码:

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

int n, m, cnt, ans = 0, num = 0;
char s[1005][1005];
int vis[1005][1005];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

bool check(int x, int y) {
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (s[nx][ny] == '#') return 0;
    }
    return 1;
}

void dfs(int x, int y, int id) {
    cnt++;
    vis[x][y] = id;
    if (!check(x, y)) return ;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
        // 这边不判s[nx][ny]=='#' 因为前面check有判过了
        if (vis[nx][ny] == vis[x][y]) continue;
        dfs(nx, ny, id);
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
    cin >> s[i][j];

    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
        if (s[i][j] == '.' && !vis[i][j]) {
            cnt = 0;
            ++num;
            dfs(i, j, num);
            ans = max(ans, cnt);
        }
    }

    cout << ans;
    return 0;
}

E题:Jump Distance Sum

标签:思维
题意:在坐标平面上,有 N N N个点 P 1 , P 2 , … , P N P_1,P_2,…,P_N P1​,P2​,…,PN​,其中点 P i P_i Pi​的坐标为 ( X i , Y i ) (X_i,Y_i) (Xi​,Yi​)。
两点 A A A与 B B B之间的距离 d i s t ( A , B ) dist(A,B) dist(A,B)定义如下:
一只兔子最初位于点 A A A。位置为 ( x , y ) (x,y) (x,y)的兔子可以跳跃到
( x + 1 , y + 1 ) 、 ( x + 1 , y − 1 ) 、 ( x − 1 , y + 1 ) (x+1,y+1) 、 (x+1,y−1) 、 (x−1,y+1) (x+1,y+1)、(x+1,y−1)、(x−1,y+1)或 ( x − 1 , y − 1 ) (x−1,y−1) (x−1,y−1) 。
d i s t ( A , B ) dist(A,B) dist(A,B)被定义为从 A A A点到 B B B点所需的最少跳跃次数。
如果经过任意次数的跳跃都无法从点 A A A到达点 B B B,则设为 d i s t ( A , B ) = 0 dist(A,B)=0 dist(A,B)=0。
计算总和 ∑ i = 1 N − 1 ∑ j = i + 1 N dist ( P i , P j ) \displaystyle\sum_{i=1}^{N-1}\displaystyle\sum_{j=i+1}^N \text{dist}(P_i,P_j) i=1∑N−1​j=i+1∑N​dist(Pi​,Pj​)
题解:兔子的移动是对角移动,不太方便进行操作。我们可以把坐标轴旋转 45 % 45\% 45%,并缩放 2 \sqrt2 2 ​倍。那么 ( x , y ) (x,y) (x,y)点移动到 ( x + y , x − y ) (x+y,x-y) (x+y,x−y)。比如 ( 2 , 2 ) (2,2) (2,2)变成 ( 2 2 , 0 ) (2\sqrt2,0) (22 ​,0),放大 2 \sqrt2 2 ​倍,为 ( 4 , 0 ) (4,0) (4,0)。
原来位置为 ( x , y ) (x,y) (x,y)的兔子可以跳跃到
( x + 1 , y + 1 ) 、 ( x + 1 , y − 1 ) 、 ( x − 1 , y + 1 ) (x+1,y+1) 、 (x+1,y−1) 、 (x−1,y+1) (x+1,y+1)、(x+1,y−1)、(x−1,y+1)或 ( x − 1 , y − 1 ) (x−1,y−1) (x−1,y−1) 。
我们转换后兔子可以从 ( x + y , x − y ) (x+y,x-y) (x+y,x−y)跳跃到 ( x + y + 2 , x − y ) 、 ( x + y , x − y + 2 ) 、 ( x + y , x − y − 2 ) (x+y+2,x−y)、 (x+y,x−y+2) 、 (x+y,x−y−2) (x+y+2,x−y)、(x+y,x−y+2)、(x+y,x−y−2)和 ( x + y − 2 , x − y ) (x+y−2,x−y) (x+y−2,x−y)
转换成更通用的式子:兔子可以从 ( x , y ) (x,y) (x,y)跳跃到 ( x + 2 , y ) 、 ( x , y + 2 ) 、 ( x , y − 2 ) (x+2,y)、 (x,y+2) 、 (x,y−2) (x+2,y)、(x,y+2)、(x,y−2)和 ( x − 2 , y ) (x−2,y) (x−2,y)
那么我们观察到每次跳跃的距离都是偶数,也就是说如果 A = ( x 1 , y 1 ) , B = ( x 2 , y 2 ) A=(x_1,y_1),B=(x_2,y_2) A=(x1​,y1​),B=(x2​,y2​), ∣ x 1 − x 2 ∣ |x_1-x_2| ∣x1​−x2​∣不能被 2 2 2整除,或者 ∣ y 1 − y 2 ∣ |y_1-y_2| ∣y1​−y2​∣不能被 2 2 2整除,那么兔子就无法从 A A A到达 B B B。
对于能到达的情况跳跃的最少次数显然等于 1 2 ( ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ ) \frac{1}{2}(\lvert x_1-x_2\rvert+\lvert y_1-y_2\rvert) 21​(∣x1​−x2​∣+∣y1​−y2​∣)。
也就是说对于能够相互到达的两个点 A A A和 B B B,他们的转化后的 x x x坐标的奇偶性和 y y y坐标的奇偶性必须相同。
我们可以统计一下对应转化后的 x x x奇/偶, y y y奇/偶的情况。然后去求一下对应情况下的跳跃次数。
这边举个例子:假设 x x x奇, y y y奇的情况,得到的 x x x的序列为
1     3     8     13 1\ \ \ 3\ \ \ 8\ \ \ 13 1   3   8   13
第二个 3 到 1 的距离为 1 段 2 的距离。
第三个 8 到前面两个点的距离为 2 段 8 的距离减去前缀前两个距离之和,即 2 ∗ 8 − ( 1 + 3 ) 2*8-(1+3) 2∗8−(1+3)
第四个 13 到前面两个点的距离为 3 段 13 的距离减去前缀 3 个距离之和,即 3 ∗ 13 − ( 1 + 3 + 8 ) 3*13-(1+3+8) 3∗13−(1+3+8)
注意题目中,转化后是 2 2 2的距离跳的,所以跳跃的次数最后要除以 2 2 2。
代码:

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

typedef long long ll;
ll n, X, Y, ans = 0;
vector<ll> x[2][2], y[2][2];

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> X >> Y;
        x[(X+Y)%2][abs(X-Y)%2].push_back(X+Y);
        y[(X+Y)%2][abs(X-Y)%2].push_back(X-Y);
    }

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            int nx = x[i][j].size();
            int ny = y[i][j].size();
            if (nx == 0) continue;

            sort(x[i][j].begin(), x[i][j].end());
            sort(y[i][j].begin(), y[i][j].end());

            ll prex = x[i][j][0], prey = y[i][j][0];;
            for (int k = 1; k < nx; k++) {
                ans += k * x[i][j][k] - prex;
                prex += x[i][j][k];
            }
            for (int k = 1; k < ny; k++) {
                ans += k * y[i][j][k] - prey;
                prey += y[i][j][k];
            }
        }
    }

    cout << ans / 2;
    return 0;
}

F题:Double Sum

标签:扫描线、树状数组、线段树
题意:给定序列 A A A,计算 ∑ i = 1 N ∑ j = i + 1 N max ⁡ ( A j − A i , 0 ) \displaystyle \sum_{i=1}^N \sum_{j=i+1}^N \max(A_j - A_i, 0) i=1∑N​j=i+1∑N​max(Aj​−Ai​,0)
题解:观察公式,我们按照顺序遍历序列 A A A中的数,固定 A j A_j Aj​,就变成了求当前数字和前面所有比自己小的数字之差的和。即公式: ∑ i = 1 j − 1 A j − A i \displaystyle \sum_{i=1}^{j-1} A_j - A_i i=1∑j−1​Aj​−Ai​在满足条件 A j > A i A_j\gt A_i Aj​>Ai​的情况下。
我们将这个式子展开: A j ∑ i = 1 j − 1 − ∑ i = 1 j − 1 A i A_j\displaystyle \sum_{i=1}^{j-1} - \displaystyle \sum_{i=1}^{j-1}A_i Aj​i=1∑j−1​−i=1∑j−1​Ai​在满足条件 A j > A i A_j\gt A_i Aj​>Ai​的情况下。
通俗点讲,假设对于 A j A_j Aj​来说,在它前面有 m m m个比它小的数 A i A_i Ai​,那么值就是 m m m个 A j A_j Aj​之和减去所有在第 j j j个数之前比它小的 A i A_i Ai​之和。这个东西可以通过树状数组或者线段树进行维护。这题数据量比较大,需要离散化处理下。
代码:

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

typedef long long ll;
const ll N = 4e5 + 10;
ll n, b[N], num[N], sum[N], ans = 0;
struct node {
    ll a, id;
}p[N];

bool cmp1(node x, node y) {
    if (x.a == y.a) return x.id < y.id;
    return x.a < y.a;
}

bool cmp2(node x, node y) {
    return x.id < y.id;
}


ll lowbit(ll x) {
    return x & (-x);
}

void update(ll *tree, ll x, ll k) {
    for (ll i = x; i <= n; i += lowbit(i)) tree[i] += k;
}

ll query(ll *tree, ll x) {
    ll res = 0;
    for (ll i = x; i > 0; i -= lowbit(i)) res += tree[i];
    return res;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> p[i].a;
        p[i].id = i;
    }
    sort(p + 1, p + 1 + n, cmp1);
    for (int i = 1; i <= n; i++) b[p[i].id] = i;
    sort(p + 1, p + 1 + n, cmp2);
    for (int i = 1; i <= n; i++) {
        ans += p[i].a * query(num, b[i] - 1);
        ans -= query(sum, b[i] - 1);
        update(num, b[i], 1);
        update(sum, b[i], p[i].a);
    }
    cout << ans;
    return 0;
}
ABC 315 题解 题目质量较高,特别是 F。建议 D 和 E 对调。 阅读详情

相关推荐

Windows下TensorRT+YOLOv11部署避坑指南:从CUDA配置到模型加密全流程

本文详细解析了在Windows平台部署YOLOv11与TensorRT的全流程,重点涵盖从CUDA环境配置、工程编译适配到模型加密保护的实战指南。基于wang-xinyu的tensorrtx仓库,提供了详细的版本选择、编译问题修复方案,并深入探讨了如何对TensorRT引擎进行加密,以实现高效且安全的端到端部署。

vscode5coder的博客 449

ABC351 做题记录

ABC 351 做题记录。

m0_73116155的博客 412

AD620仪表放大器模组实战:从调零到信号放大的完整指南

本文详细介绍了AD620仪表放大器模组的实战应用,从调零到信号放大的完整指南。AD620模组以其专业级性能和易用性成为微弱信号放大的首选,集成了AD620芯片、LM358运放和7660电源转换芯片。文章提供了调零技巧、增益设置方法以及单端与差分输入的正确连接方案,并通过心电信号采集和称重传感器等实际案例展示了其广泛应用。

weixin_29290379的博客 376

AtCoder Beginner Contest 315 题解 A~E

AtCoder Beginner Contest 315 题解 A~E,模拟题,思维题,枚举,拓扑排序

xiaoqian7758258的博客 593

Gromacs实战:从蛋白质-小分子对接到分子动力学模拟全流程解析

本文详细解析了使用Gromacs进行蛋白质-小分子复合物分子动力学模拟的全流程。从处理AutoDock等对接软件的结果文件开始,逐步指导如何为蛋白质和小分子分别生成拓扑文件,并解决力场合并的核心挑战。文章涵盖了构建模拟盒子、添加溶剂离子、能量最小化、平衡模拟以及关键的轨迹分析步骤,为计算生物学和药物设计研究者提供了一套从静态对接到动态评估的完整实战指南。

weixin_29251337的博客 1218

librealsense2 camera.so: undefined symbol:ZN2cV3MatC1EV解决笔记记录

先参考的这个兄弟的办法虽然没解决但是提供了大方向感谢; realsenseD400系列相机报错:undefined symbol: _ZN2cv3MatC1EiiiRKNS_7Scalar_IdEE解决方案 后解决办法参考 No GPU usage on jetson xavier NX · Issue #2326 · IntelRealSense/realsense-ros · GitHubOpenCV_DIR" to a directory containing one of the above f

梁俊星的博客 3514

Atcoder ABC351 A-E 题解

atcoder题解351

2301_76204446的博客 915

Python金融数据获取工具库之baostock使用详解

在金融数据分析和量化交易中,获取准确及时的市场数据是非常重要的。baostock是一个专门为中国股市数据提供支持的 Python 库,它提供了免费的股票数据接口,用户可以方便地获取股票、指数、基金等各种金融数据。本文将详细介绍baostock库,包括其安装方法、主要特性、基本和高级功能,以及实际应用场景,帮助全面了解并掌握该库的使用。

Rocky006的博客 5340

AtCoder Beginner Contest 351(ABC 351) A-F题解

Atcoder Beginner Contest 351(ABC351)A-F题解

m0_63247322的博客 960

超声波测距的15度魔法:HC-SR04测量角度特性在机器人避障中的实战技巧

本文深入探讨了HC-SR04超声波测距模块在机器人避障中的15度测量角度特性及其应用技巧。通过分析15度角的工程意义、多模块阵列设计、狭小空间优化方案及温度补偿技术,帮助开发者提升机器人环境感知能力。文章特别强调了HC-SR04模块在低成本避障方案中的核心优势与实战优化策略。

weixin_29172963的博客 430

Anylogic试用版密匙

#$%99dTMbLIj+hm/c9fn0suWlfQjdK9FzRH8oSbR Rbm3FEeONkF5mDLKHxhscEDBANDg4BSU2Oi6hErk TH/KzwiCtsM0jfD50uRsj60+gi9ifTlduwcpSr6a GtVSilXwF997xTVAoMLddqOzGQAbnSjBiJOBdm1Z 0QwwIEJynvYgckLfoEADzncIgNnJjYshWcmGh3s9 gTgyuQPlRBeTXfb+ZJPI1JGi4sAUljwdB53Df+AX SEf5FaIbih

qq_43939616的博客 8264

AtCoder Beginner Contest 351 (ABCDEF题)视频讲解

AtCoder Beginner Contest 351 A、B、C、D、E、F题视频讲解

Edward Shi的博客 1622

淘宝x-mini-wua生成机制与硬件信息关联性深度解析

本文深度解析了淘宝x-mini-wua的生成机制与硬件信息的关联性,详细介绍了其作为设备指纹令牌的核心作用及技术实现细节。通过分析基础硬件层、环境特征层和行为特征层的数据采集,揭示了淘宝如何利用AES加密和分级加密策略防止破解,并探讨了其安全防护与对抗策略。

weixin_29243279的博客 228

AtCoder Beginner Contest 351

AtCoder Beginner Contest 351

青少年趣味编程 979

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

AtCoder Beginner Contest 288

AtCoder Beginner Contest 288

青少年趣味编程 1626

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

AtCoder Beginner Contest 301

AtCoder Beginner Contest 301

青少年趣味编程 1576

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

AtCoder Beginner Contest 287

AtCoder Beginner Contest 287

青少年趣味编程 1862

AtCoder Beginner Contest 174

AtCoder Beginner Contest 174

青少年趣味编程 1387

AtCoder Beginner Contest 329

AtCoder Beginner Contest 329

青少年趣味编程 973

AtCoder Beginner Contest 334

AtCoder Beginner Contest 334

青少年趣味编程 1008

AtCoder Beginner Contest 284

AtCoder Beginner Contest 284

青少年趣味编程 936

AtCoder Beginner Contest 275

AtCoder Beginner Contest 275

青少年趣味编程 827

AtCoder Beginner Contest 362

AtCoder Beginner Contest 362

青少年趣味编程 645

AtCoder Beginner Contest 246

AtCoder Beginner Contest 246

青少年趣味编程 1200

AtCoder Beginner Contest 346

AtCoder Beginner Contest 346

青少年趣味编程 986

Atcoder Beginner Contest 220

Atcoder Beginner Contest 220

青少年趣味编程 1106
上一篇: 上海计算机学会 2024年4月月赛 丙组T4 排序分数
下一篇: AtCoder Beginner Contest 351 A题 The bottom of the ninth
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值