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

AtCoder Beginner Contest 409

AtCoder Beginner Contest 409

A题

知识点:枚举

题意为给了两个长度为 N N N的字符串S1S2,字符串仅包含ox字符,问两个字符串是否存在一个位置i使得S1[i]==S2[i]&&S1[i]=='o'。时间复杂度为 O ( n ) O(n) O(n)

void solve(){int n;cin >> n;string s1,s2;cin >> s1 >> s2;for(int i=0;i<n;i++){if(s1[i]==s2[i]&&s1[i]=='o'){cout << "Yes" << endl;return;}}cout << "No" << endl;
}

B题

知识点:枚举,排序+二分查找

题目陈述

给定一个长度为 N N N的非负整数序列 A = ( A 1 , A 2 , … , A N ) A = (A_1, A_2, \ldots, A_N) A=(A1,A2,,AN)。找出满足以下条件的最大非负整数 x x x

  • A A A中,大于或等于 x x x的元素出现次数(包括重复元素)至少为 x x x次。

约束条件

  • 1 ≤ N ≤ 100 1 \leq N \leq 100 1N100
  • 0 ≤ A i ≤ 10 9 0 \leq A_i \leq 10^9 0Ai109
  • 所有输入值均为整数。

解法:由于题目中要找大于等于 x x x的元素个数,所以可以对序列 A A A进行升序排序。序列最大长度不超过100,所以我们可以从0到100枚举 x x x,看那一个符合条件即可。可以使用lower_bound()函数获得大于等于 x x x的元素个数。时间复杂度为 O ( n × log ⁡ n ) O(n\times \log{n}) O(n×logn)

void solve(){int n;cin >> n;vector<int> a(n+1);for(int i=1;i<=n;i++){cin >> a[i];}sort(a.begin()+1,a.end());int x=0;for(int i=1;i<=n;i++){//枚举xint idx=lower_bound(a.begin()+1,a.end(),i)-a.begin();if(n-idx+1>=i) x=i;}cout << x << endl;
}

C题

知识点:思维,枚举

题目陈述

有一个周长为 L L L的圆,圆上放置了点 1 , 2 , … , N 1, 2, \ldots, N 1,2,,N。对于 i = 1 , 2 , … , N − 1 i = 1, 2, \ldots, N - 1 i=1,2,,N1,点 i + 1 i + 1 i+1位于点 i i i沿顺时针方向 d i d_i di距离的位置上。

请找出满足以下两个条件的整数三元组 ( a , b , c ) (a, b, c) (a,b,c) 1 ≤ a < b < c ≤ N 1 \leq a < b < c \leq N 1a<b<cN)的数量:

  • a a a b b b c c c都处于不同的位置。
  • 以点 a a a b b b c c c为顶点的三角形是等边三角形。

约束条件

  • 3 ≤ L , N ≤ 3 × 10 5 3 \leq L, N \leq 3 \times 10^5 3L,N3×105
  • 0 ≤ d i < L 0 \leq d_i < L 0di<L
  • 所有输入值均为整数。

解法:要出现等边三角形,肯定三个点中任意两个点之间的圆弧长度为 L 3 \frac{L}{3} 3L,点1的位置为0,每个点在圆周上的位置一定是一个整数,所以如果3不能整除 L L L,那么一定不存在这样的等边三角形,输出为0。否则我们计算每一个点在圆周上的位置,并且用一个 c n t cnt cnt记录每个位置点的数量,之后枚举每一个位置,计算另外两个点的位置,统计答案。这样会有一个问题就是每一个等边三角形会被重复统计,比如枚举到a点时,找到另外两个点b和c,那么枚举到b时,会找到a和c,枚举到c时,会找到a和b,那么就统计了三次,所以最后对答案除以3就是最终的答案了。时间复杂度为 O ( n ) O(n) O(n)

void solve(){int n,L;cin >> n >> L;vector<int> d(n);for(int i=1;i<n;i++) cin >> d[i];if(L/3*3!=L){cout << 0 << endl;return;}vector<int> loca(n+1);int s=0;loca[1]=s;for(int i=1;i<n;i++){s=(s+d[i])%L;loca[i+1]=s;}vector<int> cnt(L,0);for(int i=1;i<=n;i++){cnt[loca[i]]++;}int ans=0,deg=L/3;//枚举每一个位置for(int i=0;i<L;i++){int p=(i+deg)%L,q=(i+2*deg)%L;ans+=cnt[i]*cnt[p]*cnt[q];}cout << ans/3 << endl;
}

D题

知识点:贪心

问题陈述

给定一个长度为 N N N、由小写英文字母组成的字符串 S = S 1 S 2 … S N S = S_1S_2\ldots S_N S=S1S2SN。你需要对 S S S恰好执行一次以下操作:

  • 选择 S S S的一个长度至少为 1 的连续子串,将其循环左移 1 位。也就是说,选择整数 1 ≤ ℓ ≤ r ≤ N 1 \leq \ell \leq r \leq N 1rN,把 S ℓ S_\ell S插入到 S S S的第 r r r个字符右侧,然后删除 S S S的第 ℓ \ell 个字符。

找出执行该操作后,所有可能得到的字符串中字典序最小的那个。

你会拿到 T T T组测试用例,请分别解决每个测试用例。

约束条件

  • 1 ≤ T ≤ 10 5 1 \leq T \leq 10^5 1T105
  • 1 ≤ N ≤ 10 5 1 \leq N \leq 10^5 1N105
  • S S S是长度为 N N N、由小写英文字母组成的字符串。
  • T T T N N N是整数。
  • 单个输入文件中所有测试用例的 N N N之和最多为 10 5 10^5 105

解法:说到字典序,我们就会想到贪心的思想。在循环左移一次后,要使得字符串字典序是操作后最小的那个,那么肯定是找到第一个 s i > s i + 1 s_i>s_{i+1} si>si+1的位置 l l l,循环左移后 s i = s i + 1 s_i=s_{i+1} si=si+1。现在考虑字串的右端点 r r r,要将 s l s_l sl移动到后面某个位置,且满足在 l + 2 l+2 l+2到结束的某个位置 j j j使得 s j > s l s_j>s_l sj>sl,那么 r = j − 1 r=j-1 r=j1。如果不存在大于 s l s_l sl的,那么就把 s l s_l sl放在最后。这样一定是最小的,也很容易证明。最后答案就是拼接就好,可以看到上面操作至少包含了3个字符,所以对于 n ≤ 2 n \leq 2 n2的情况,我们单独处理。时间复杂度为 O ( n ) O(n) O(n)代码写的不是太好

void solve(){int n;cin >> n;string s;cin >> s;if(n<=2){if(n==1){cout << s << endl;}else{if(s[0]>s[1]){reverse(s.begin(),s.end());}cout << s << endl;}return;}string ans;bool find=false;for(int i=0;i<n-1;i++){if(s[i]>s[i+1]){find=true;//从i+2去找第一个大于当前字符的char c=s[i];ans=s.substr(0,i);ans+=s[i+1];int r=n-1,f=0;for(int j=i+2;j<n;j++){if(s[j]>c){r=j;f=1;break;}}if(f){for(int k=i+2;k<=r-1;k++) ans+=s[k];ans+=c;for(int k=r;k<n;k++) ans+=s[k];}else{for(int k=i+2;k<n;k++) ans+=s[k];ans+=c;}break;}}if(!find) cout << s << endl;else cout << ans << endl;
}

E题

知识点:树上dp

问题陈述

给定一棵有 N N N个顶点的树。顶点编号为 1 , 2 , … , N 1, 2, \ldots, N 1,2,,N,边编号为 1 , 2 , … , N − 1 1, 2, \ldots, N - 1 1,2,,N1。边 j j j双向连接顶点 u j u_j uj v j v_j vj,且权重为 w j w_j wj。此外,顶点 i i i被赋予一个整数 x i x_i xi。如果 x i > 0 x_i > 0 xi>0,则在顶点 i i i放置 x i x_i xi个正电子;如果 x i < 0 x_i < 0 xi<0,则在顶点 i i i放置 − x i -x_i xi个电子;如果 x i = 0 x_i = 0 xi=0,则顶点 i i i不放置任何粒子。已知 ∑ i = 1 N x i = 0 \sum_{i=1}^N x_i = 0 i=1Nxi=0

沿边 j j j移动一个正电子或电子需要消耗能量 w j w_j wj。当正电子和电子处于同一顶点时,它们会等量相互湮灭。

请找出使所有正电子和电子湮灭所需的最小能量。

约束条件

  • 2 ≤ N ≤ 10 5 2 \leq N \leq 10^5 2N105
  • ∣ x i ∣ ≤ 10 4 |x_i| \leq 10^4 xi104
  • ∑ i = 1 N x i = 0 \sum_{i=1}^N x_i = 0 i=1Nxi=0
  • 1 ≤ u j < v j ≤ N 1 \leq u_j < v_j \leq N 1uj<vjN
  • 0 ≤ w j ≤ 10 4 0 \leq w_j \leq 10^4 0wj104
  • 给定的图是一棵树。
  • 所有输入值均为整数。

这道题按照给出的示例模拟一下,可以发现这个就是一道树上dp的题,所以思路也很简单了,定义 d p [ i ] dp[i] dp[i]表示以 i i i为根的子树将 i i i的所有孩子向上移动能够获得的代价,由于正负电子相遇会抵消,所以要用一个 c n t [ i ] cnt[i] cnt[i]来记录每一个节点的的电子情况。之后就是列状态转移方程以及初始化等问题,可以在代码中看到。时间复杂度为 O ( n ) O(n) O(n)

示例:

5
-2 -8 10 -2 2
3 5 1
1 3 5
2 5 0
3 4 6

在这里插入图片描述

模拟一遍即可。

const int maxn=1e5+9,mod=1e9+7;
//a数组就是每个节点的电子情况,dp[i]表示以i为根的子树的花费,cnt[i]记录节点i的电子情况
int a[maxn],dp[maxn],cnt[maxn];
//tr存树
vector<pair<int,int>> tr[maxn];void dfs(int u,int p){//初始化:开始每个节点为dp[u]=0,cnt[u]=a[u]dp[u]=0;cnt[u]=a[u];for(auto[v,w]:tr[u]){if(v==p) continue;dfs(v,u);//注意这里cnt[v]要加绝对值dp[u]+=dp[v]+w*abs(cnt[v]);//湮灭电子cnt[u]+=cnt[v];}
}
void solve(){int n;cin >> n;for(int i=1;i<=n;i++) cin >> a[i];for(int i=1;i<n;i++){int u,v,w;cin >> u >> v >> w;tr[u].push_back({v,w});tr[v].push_back({u,w});}dfs(1,0);cout << dp[1] << endl;
}
http://www.xdnf.cn/news/12786.html

相关文章:

  • Continue 开源 AI 编程助手框架深度分析
  • C++17 和 C++20 中的新容器与工具:std::optional、std::variant 和 std::span
  • 学习python做表格6月8日补录
  • B站_Miachael_ee_通过GDB和OpenOCD对ESP32 进行JTAG Debug_笔记1
  • Python Day46
  • 【AI论文】MiMo-VL技术报告
  • 整数的字典序怎么算
  • 【FPGA开发】DDS信号发生器设计
  • 【题解-Acwing】1097. 池塘计数
  • OCCT基础类库介绍: Foundation Classes - Basics
  • 动手学深度学习pytorch(第一版)学习笔记汇总
  • 从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
  • 利用Pandas AI完成Excel大模型的结合实现自然语言问数
  • 第二十九章 数组
  • iptables实验
  • 2025年中国建银投资笔试测评春招校招社招笔试入职测评行测题型解读揭秘
  • 小番茄C盘清理:专业高效的电脑磁盘清理工具
  • FBRT-YOLO:面向实时航拍图像检测的轻量高效目标检测框架
  • 【QT】QT多语言切换
  • Java 线程同步详解
  • 前后端分离开发 和 前端工程化
  • k8s4部署
  • STM32H562----------串口通信(UART)
  • Spring注解开发
  • 《Go小技巧易错点100例》第三十五篇
  • CCF GESP202503 Grade4-B4263 [GESP202503 四级] 荒地开垦
  • JAVA学习 DAY4 DOS操作讲解及实例
  • 高保真组件库:下拉框
  • (一)单例模式
  • leetcode56-合并区间