AtCoder Beginner Contest 240 题解
A - Edge Checker
题目大意:
给个1 - 10 数字围成一个圈,给你两个数问你是否相邻
int main (){
IOS
int a, b; cin >> a >> b;
if (abs (a - b) == 1){
cout << "Yes" << endl;
}
else if (a == 10 && b == 1 || a == 1 && b == 10) {
cout << "Yes" << endl;
}
else cout << "No" << endl;
}
B - Count Distinct Integers
题目大意;
给一个数组,问你出现了多少不同的数字。(丢 set 里就行)
int main (){
IOS
set <int> s;
int n; cin >> n;
for (int i = 1 ; i <= n ; i ++){
int x; cin >> x;
s.insert(x);
}
cout << s.size () << endl;
return 0;
}
C - Jumping Takahashi
题目大意:
给定目的点 x, 跳跃 n 次,每次可以从 a, b 中选择一个数跳跃一定的距离。问从起点 0 开始,能否恰好跳跃到 x 点。
分析:
暴力枚举每一次选 a 或者 b, 时间复杂度 , 显然不行。考虑用 去表示前 i 次跳跃后,是否能到达 j 点。
时间复杂度 ,可以用滚动优化掉一维,但是懒得搞了qwq。
int f[105][10005];
int main (){
IOS
int n, x; cin >> n >> x;
f[0][0] = 1;
for (int i = 1 ; i <= n ; i ++){
int a, b; cin >> a >> b;
for (int j = 0 ; j <= 10000 - a ; j ++){
if (f[i - 1][j])
f[i][j + a] = f[i - 1][j];
}
for (int j = 0 ; j <= 10000 - b ; j ++){
if (f[i - 1][j])
f[i][j + b] = f[i - 1][j];
}
}
if (f[n][x]){
cout << "Yes" << endl;
}
else cout << "No" << endl;
return 0;
}
D - Strange Balls
题目大意:
类似于 “祖玛” 的游戏,一个一个往桶里添加小球,当 小球的编号与连续个数相同时,这部分小球会被消掉。求出每次添加小球后桶中小球个数。
分析:
用两个栈去维护即可,一个栈维护个数,一个栈维护桶内小球的情况,然后模拟输出即可。(一开始以为连续球必然会消去,wa了一发)
#include<bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))<eps)
#define More(a,b) (((a)-(b))>(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int a[N];
int main (){
IOS
int t; cin >> t;
stack <int> s, c;
int now = 0, cnt = 0;
while (t --){
int n; cin >> n;
if (s.empty()){
s.push(n);
now = n; cnt ++;
}
else {
if (s.top () == n){
if (cnt == n - 1){
while (s.size () > 0 && s.top () == n) s.pop();
if (s.empty()) now = 0, cnt = 0;
else{
if (c.empty()) cnt = 0;
else {
cnt = c.top(); c.pop();
}
n = s.top ();
}
}
else {
s.push(n);
cnt ++;
}
}
else {
s.push(n);
c.push(cnt);
now = n, cnt = 1;
}
}
cout << s.size () << endl;
}
return 0;
}
E - Ranges on Tree
题目大意:
给一颗根节点为 1 的树,每个节点有一个集合 , 表示以该节点为根节点的子树包含的节点数。要求给树上的所有节点,分配一个区间,使得节点之间的区间关系和 之间的关系一致。输出分配情况,同时使得所有区间的最右端最小。(用尽可能小的数去分配)
例如: 如果节点2 和节点 3 的子树没有交集,那么为这两个节点分配的区间的交集也应当为空集。如果节点 1 的子树包含节点 2 的子树,那么区间 1 也应当包含 区间 2。
分析:
显然可以看出,根节点 1 包含所有其他节点, 那么根节点的区间一定是最大的。又可以看出,每个叶子节点一定是相互独立的,所以要为每个叶子节点分配一个值。所以,根节点的长度为树中叶子节点的个数。按每颗子树的叶子节点数分配区间即可。
题目不难想,题意有点难读,我读了n个错误题意 ,比赛中实现得比较复杂,第一遍 dfs 求 每棵树的叶子节点个数,第二遍 dfs 赋值。
#include<bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))<eps)
#define More(a,b) (((a)-(b))>(eps))
#define x first
#define y second
using namespace std;
const int N=3e5+7;
const double eps=1e-6;
const int mod=1e9+7;
vector <int> a[N];
int cnt = 0;
bool st[N];
int d[N];
struct node{
int l, r;
};
node ans[N];
int dfs (int u){
bool flag = 0;
for (auto i : a[u]){
if (!st[i]){
flag = 1;
st[i] = 1;
d[u] += dfs(i);
st[i] = 0;
}
}
if (flag)
return d[u];
d[u] = 1;
return d[u];
}
void dfs2 (int u, int l){
int loc = l;
ans[u].l = l, ans[u].r = l + d[u] - 1;
for (auto i : a[u]){
if (!st[i]){
st[i] = 1;
dfs2 (i, loc);
loc += d[i];
st[i] = 0;
}
}
}
int main (){
IOS
int n; cin >> n;
for (int i = 1 ; i < n ; i ++){
int u, v; cin >> u >> v;
a[u].push_back(v);
a[v].push_back(u);
}
st[1] = 1;
dfs(1);
memset (st, 0, sizeof st);
st[1] = 1;
dfs2 (1, 1);
for (int i = 1 ; i <= n ; i ++){
cout << ans[i].l << ' ' << ans[i].r << endl;
}
return 0;
}
F - Sum Sum Max
题目大意:
给定一个数组 C,其前缀和数组 为 B , B的前缀和数组为 C,求 A 中的最大值。C数组长度为 m (< 1e9), 给出方式是 n 行读入,每行读入为 x, y。表示 C 数组中有连续的 y 个 x。
分析:
从数据范围来看, 此题暴力的复杂度是 ,行不通。试着去摸几组样例,会发现,b 是 由多个等差数列组成的。反映到坐标轴上会发现,b是由一段一段斜率不同的一次函数构成的。如下图所示
不难发现,最大值出现在两端,或者是 B 与 x = 0 的交点处(当然实际情况是离散的整数点),取 大于 0 的最小值即可。
实际写的时候,我每一段的右端点和 0 点都更新了答案。
#include<bits/stdc++.h>
#define int long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))<eps)
#define More(a,b) (((a)-(b))>(eps))
#define x first
#define y second
#define endl '\n'
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int x[N], y[N];
signed main (){
IOS
int t; cin >> t;
while (t --){
int n, m; cin >> n >> m;
for (int i = 1 ; i <= n ; i ++) cin >> x[i] >> y[i];
int ans = x[1], now = 0, sum = 0;
for (int i = 1 ; i <= n ; i ++){
int l = now + x[i], r = now + x[i] * y[i];
ans = max (sum + l, ans);
if (x[i] < 0 && r < 0 && l > 0){
int step = abs (x[i]);
int tr = l - l / step * step;
ans = max (sum + (tr + l) * ((tr - l) / x[i] + 1) / 2, ans);
}
sum += (l + r) * y[i] / 2;
now = r;
ans = max (sum, ans);
}
cout << ans << endl;
}
return 0;
}
其实本题应该是可以写出来的,赛中较为可惜。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】