当前位置: 首页 > news >正文

AtCoder Beginner Contest 348 A~F

A. Penalty Kick(循环)

题意

n n n轮比赛,已知在第 i i i轮比赛中,如果 i i i 3 3 3的倍数,那么将会输掉这场比赛,否则将会赢下这场比赛,请你输出一个序列表示每轮比赛的结果(o表示赢,x表示输)。

分析

使用循环进行判断输出即可。

代码

#include<bits/stdc++.h>
using namespace std;void solve() {int n;cin >> n;for (int i = 1; i <= n; i++) {if (i % 3 == 0) {cout << "x";} else {cout << "o";}}
}int main() {solve();return 0;
}

B.Farthest Point(枚举)

题意

给出二维坐标系上的 N N N个点,请你输出每个点距离最远的点的编号是什么(只比较与其他 N − 1 N - 1 N1个点的距离,如果存在多个距离相等的点,输出编号最小的一个)。

分析

对于每个点,枚举其他的 N − 1 N - 1 N1个点,记录距离最远的点即可。

代码

#include<bits/stdc++.h>
using namespace std;int x[105], y[105];void solve() {int n;cin >> n;for (int i = 1; i <= n; i++) cin >> x[i] >> y[i];for (int i = 1; i <= n; i++) {int len = -1, id = i;for (int j = 1; j <= n; j++) {int l = (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);if (l > len) {len = l;id = j;}}cout << id << endl;}
}int main() {solve();return 0;
}

C.Colorful Beans(map)

题意

N N N种糖豆,每种糖豆都有一个美味值以及一个颜色,由于所有豆子都被混在一起,我们只能根据颜色来分辨出不同的豆子。

请你选出一种颜色的一个豆子,问能获得的最大的最小美味值是多少。

分析

考虑最坏情况,即无论选择哪种颜色的豆子,被选出的豆子均为该颜色豆子中美味值最小的一个,那么可以将所有颜色的豆子均视为只存在美味值最低的那一颗,然后统计所有颜色豆子美味值最低的那一颗中的最大值即可,由于数据规模较大,可以使用map对颜色和美味值进行存储。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;map<ll, ll> P;void solve() {int n;cin >> n;for (int i = 1; i <= n; i++) {ll a, c;cin >> a >> c;if (P.find(c) == P.end()) {P[c] = a;} else {P[c] = min(P[c], a);}}ll maxn = -1;for (auto i : P) {maxn = max(maxn, i.second);}cout << maxn << endl;
}int main() {solve();return 0;
}

D.Medicines on Grid(DFS)

题意

有一个 H × W H \times W H×W的网格,网格中每个 1 × 1 1 \times 1 1×1的小方格中包含以下四种内容之一:

  • '.':表示空格子

  • '#':表示存在一个障碍物

  • 'S':表示起点

  • 'T':表示终点

每次移动到四方向上相邻的格子中,均会消耗 1 1 1点能量,当能量为 0 0 0时,将不能再移动。

在网格中,其中 N N N个格子中包含着药品,使用第 i i i个药品会将能量值设置为 E i E_i Ei。他只能在这个药品对应的格子上使用药品,不能将药品带出格子,且药品使用后就会消失。

问:以 0 0 0点初始能量从起点出发,能否到达终点。

分析

本题看上去是一个经典的DFS问题,但数据规模较大,如果想要使用DFS算法通过,需要优化掉很多多余的操作。

优化1:inline关键字

DFS函数前加上inline关键字,降低函数调用开销

inline void dfs(...) {...
}

优化2:找到答案后就不需要搜索了

由于题目只问是否有解,那么可以使用变量 f l a g flag flag记录是否找到过答案,到达终点后将 f l a g flag flag标记为 1 1 1,并在 d f s dfs dfs开头进行判断,如果 f l a g = 1 flag = 1 flag=1,直接return,不需要继续查找。

Tips: 本优化在极限数据下无效

优化3:当前解不可能为最优解的就排除掉

对于多次到达某个点,可以想到,如果之前到达点 ( i , j ) (i, j) (i,j)的剩余能量更多,那么我们当前继续走下去必然不会比前面方案更优,因此,可以使用一个 m a x n maxn maxn数组,使用 m a x n [ i ] [ j ] maxn[i][j] maxn[i][j]表示曾经到达点 ( i , j ) (i, j) (i,j)的最大能量,并在dfs开头判断,如果当前走到这个点的能量不如记录的 m a x n [ i ] [ j ] maxn[i][j] maxn[i][j],直接return

优化4:去掉多余判断

由于网格上进行搜索需要判断是否出界和点是否为障碍物,因此需要额外的5条判断代码,我们可以想办法把这5条代码优化掉。

maxn数组初始化为极大值,然后将所有能走的点('.', 'S'. 'T')修改为-1,同时将坐标均设置为从 1 1 1开始,即行为 1 ∼ h 1 \sim h 1h,列为 1 ∼ w 1 \sim w 1w,那么所有不能走的点的maxn数组记录的值均为极大值,如果走到该点就会直接return,不再需要对边界以及不能走的点进行判断。

代码(可以在C++20下通过)

#include<bits/stdc++.h>
using namespace std;int h, w, fx, fy;
char c[305][305];int e[305][305], vis[305][305];int flag;inline void dfs(int x, int y, int cnt) {if (flag || cnt <= vis[x][y]) return;if (c[x][y] == 'T') {flag = 1;return;}cnt = cnt < e[x][y] ? e[x][y] : cnt;vis[x][y] = cnt;if (!cnt) return;int num = e[x][y];e[x][y] = 0;dfs(x + 1, y, cnt - 1);dfs(x - 1, y, cnt - 1);dfs(x, y - 1, cnt - 1);dfs(x, y + 1, cnt - 1);e[x][y] = num;
}void solve() {cin >> h >> w;memset(vis, 0x3f, sizeof(vis));for (int i = 1; i <= h; i++) {for (int j = 1; j <= w; j++) {cin >> c[i][j];if (c[i][j] == 'S') {fx = i;fy = j;}if (c[i][j] != '#') {vis[i][j] = -1;}}}int n;cin >> n;for (int i = 1; i <= n; i++) {int r, C, E;cin >> r >> C >> E;e[r][C] = max(e[r][C], E);}dfs(fx, fy, 0);if (flag == 1) cout << "Yes" << endl;else cout << "No" << endl;
}int main() {solve();return 0;
}

E.Minimize Sum of Distances(DFS)

题意

给出一个包含 N N N个点, N − 1 N - 1 N1条边的无向图(保证给出的图是一棵树),图上第 i i i条边连接着点 a i a_i ai b i b_i bi

给出一个序列 C = ( C 1 , C 2 , … , C N ) C = (C_1, C_2, \ldots, C_N) C=(C1,C2,,CN) C i C_i Ci表示结点 i i i的权值。并定义 d ( a , b ) d(a, b) d(a,b)为点 a a a b b b之间的距离。并对于每个节点 x ( x = 1 , 2 , … , N ) x(x = 1, 2, \ldots, N) x(x=1,2,,N),定义 f ( x ) = ∑ i = 1 N ( C i × d ( x , i ) ) f(x) = \sum\limits_{i = 1}^{N}(C_i \times d(x, i)) f(x)=i=1N(Ci×d(x,i)),请你找到 m i n 1 ≤ v ≤ N f ( v ) \mathop{min}\limits_{1 \le v \le N}f(v) 1vNminf(v)

分析

假设以节点 k k k为根节点,那么 f ( k ) f(k) f(k)实际上就是 ∑ i = 1 N ( C i × d e e p [ i ] ) \sum\limits_{i = 1}^{N}(C_i \times deep[i]) i=1N(Ci×deep[i])(根节点深度为0),因此每个点到达根节点的距离就等于深度。

然后考虑树上每个节点 x x x f ( x ) f(x) f(x)是多少,不难想到,当从子树的根节点走向某个子结点时,与走向的子结点中包含的所有结点的距离均会减少 1 1 1,而与树上其他所有结点的距离都会增加 1 1 1,因此,可以使用数组 s u m C [ i ] sum_C[i] sumC[i]记录以 i i i为根节点的子树的节点权值之和,而整棵树的权值之和减去该子树的权值之和即为需要加上的部分,即:

  • f ( v ) = f ( u ) − s u m C [ v ] + s u m C [ 1 ] − s u m C [ v ] = f ( u ) + s u m C [ 1 ] − 2 ∗ s u m C [ v ] ; f(v) = f(u) - sum_C[v] + sum_C[1] - sum_C[v] = f(u) + sum_C[1] - 2 * sum_C[v]; f(v)=f(u)sumC[v]+sumC[1]sumC[v]=f(u)+sumC[1]2sumC[v];(这里以结点1作为根节点,v为u的直接子结点)

任选一个结点建树,并维护 s u m C sum_C sumC数组,然后再使用一次dfs,枚举所有树上的点,记录最小的 f ( i ) f(i) f(i)即为最后的答案。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5e2;vector<int> G[N];
ll n, deep[N], C[N], sum_C[N], ans;void dfs(int u, int pre) {ans += deep[u] * C[u];sum_C[u] = C[u];for (auto v : G[u]) {if (v == pre) continue;deep[v] = deep[u] + 1;dfs(v, u);sum_C[u] += sum_C[v];}
}void dfs2(int u, int pre, ll sum) {for (auto v : G[u]) {if (v == pre) continue;ll cnt = sum + sum_C[1] - 2 * sum_C[v];ans = min(ans, cnt);dfs2(v, u, cnt);}
}void solve() {cin >> n;for (int i = 2; i <= n; i++) {int a, b;cin >> a >> b;G[a].push_back(b);G[b].push_back(a);}for (int i = 1; i <= n; i++) cin >> C[i];dfs(1, -1);dfs2(1, -1, ans);cout << ans << endl;
}int main() {solve();return 0;
}

F.Oddly Similar(bitset)

题意

给出 N N N个包含 M M M个元素的序列,如果两个序列 X X X Y Y Y满足相同下标上相同的数字数量为奇数的话,那么就认为这两个序列是相似的,问:给出的 N N N个序列中,有多少对序列是相似的。

分析

考虑使用 b i t s e t bitset bitset进行优化,使用 b t [ i ] [ j ] [ k ] bt[i][j][k] bt[i][j][k]表示第 i i i列数字 j j j在第 k k k行的状态,当 b t [ i ] [ j ] [ k ] = 1 bt[i][j][k] = 1 bt[i][j][k]=1表示第 k k k行第 i i i列上的数字为 j j j

那么为什么要这么做呢?

首先,要想知道前面的 1 ∼ k − 1 1 \sim k - 1 1k1行有多少个数字与当前这一行的第 i i i列的数字相同,那么只需要检查 b t [ i ] [ j ] bt[i][j] bt[i][j]表示的二进制串上有多少个 1 1 1即可。

怎么判断前面所有行中多少行相同下标的数字数量为奇数呢?

使用一个 b i t s e t bitset bitset T T T表示第 k k k行与前面 k − 1 k - 1 k1行的相似情况,即使用 T [ x ] = 1 T[x] = 1 T[x]=1表示第 x x x行与第 k k k行相似。由于奇数个相同才算相似,因此,让每列相同的行状态二进制串 b t [ i ] [ j ] bt[i][j] bt[i][j] T T T进行异或运算,那么结束运算后,如果某行与第 k k k行有奇数个想同下标相同的数字,那么结果的二进制串中对应位置必然为 1 1 1,否则为 0 0 0

每轮记录 T T T中包含多少个 1 1 1,即为当前第 k k k行与前面 k − 1 k - 1 k1行有多少行相似。

代码

#include <bits/stdc++.h>using namespace std;const int N = 2005, M = 1005;int n, m, a[N][N];
bitset<N> T, bt[N][M];void solve() {cin >> n >> m;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> a[i][j];}}int ans = 0;for (int i = 0; i < n; i++) {T.reset();for (int j = 0; j < m; j++) {T ^= bt[j][a[i][j]];bt[j][a[i][j]].set(i);}ans += T.count();}cout << ans << endl;
}int main() {solve();return 0;
}

赛后交流

在比赛结束后,会在交流群中给出比赛题解,同学们可以在赛后查看题解进行补题。

群号: 704572101,赛后大家可以一起交流做题思路,分享做题技巧,欢迎大家的加入。

相关文章:

  • 基于拉格朗日分布算法的电动汽车充放电调度MATLAB程序
  • Android 事件分发
  • 美团一面4/9
  • 记Kubernetes(k8s):访问 Prometheus UI界面:Warning: Error fetching server time
  • 10. TypeScript面向对象的类(Class)
  • vue2转vue3一些属性使用方法总结 (持续更新中)
  • MySql并发事务问题
  • winform datagridView 一次删除20000条数据
  • SpringBoot快速入门笔记(5)
  • GPT提示词分享 —— 中医
  • mysql中表的设计
  • 帝国CMS模板源码整站安装说明(图文)
  • APIFY集成客服系统:提升用户运营效率
  • 技术 SEO 初学者指南
  • hadoop:案例:将顾客在京东、淘宝、多点三家平台的消费金额汇总,然后先按京东消费额排序,再按淘宝消费额排序
  • #Java异常处理
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 2017-08-04 前端日报
  • classpath对获取配置文件的影响
  • CSS魔法堂:Absolute Positioning就这个样
  • Go 语言编译器的 //go: 详解
  • go语言学习初探(一)
  • hadoop集群管理系统搭建规划说明
  • Node项目之评分系统(二)- 数据库设计
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 诡异!React stopPropagation失灵
  • 基于遗传算法的优化问题求解
  • 免费小说阅读小程序
  • 你不可错过的前端面试题(一)
  • 七牛云假注销小指南
  • 如何学习JavaEE,项目又该如何做?
  • 事件委托的小应用
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 数据库巡检项
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​渐进式Web应用PWA的未来
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (3)nginx 配置(nginx.conf)
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (四)linux文件内容查看
  • (一)kafka实战——kafka源码编译启动
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • .NET/C# 使用反射注册事件
  • .net6Api后台+uniapp导出Excel
  • .NET导入Excel数据
  • .NET值类型变量“活”在哪?
  • [20160902]rm -rf的惨案.txt
  • [Angular] 笔记 20:NgContent