当前位置:网站首页>【CodeTON Round 2 (Div. 1 + Div. 2, Rated, Prizes!)(A~D)】
【CodeTON Round 2 (Div. 1 + Div. 2, Rated, Prizes!)(A~D)】
2022-08-02 00:13:00 【浪漫主义狗】
更好的阅读体验 \color{red}{更好的阅读体验} 更好的阅读体验
文章目录
A. Two 0-1 Sequences
题目大意
- 给定只包含 0 0 0和 1 1 1的字符串 a a a和 b b b
- 对 a a a进行操作:
- 将 a 2 = m i n ( a 1 , a 2 ) a_2 = min(a_1,a_2) a2=min(a1,a2),并删除 a 1 a_1 a1,使得 a 2 a_2 a2变为新的 a 1 a_1 a1
- 将 a 2 = m a x ( a 1 , a 2 ) a_2 = max(a_1,a_2) a2=max(a1,a2),并删除 a 1 a_1 a1,使得 a 2 a_2 a2变为新的 a 1 a_1 a1
- 上述操作不限次数,求最终是否可以使得 a = b a=b a=b
思想
由于我们只能对
a[1], a[2]进行操作观察
string a, b,发现:先将
a和b的最左端对齐a = "00100101" b = "1101"与
b[0]对其的a[4]不相等,b[0]之后对齐的与a[4]之后的元素均相等若使得
a == b,则a[4]之前的元素中,必然存在某元素a[i] == b[0],才可通过相关操作使得a[4] == b[0]
由此可知,我们设
b[0]与a[k]对齐从
a[k + 1]开始构造a的字串s1,从b[1]开始构造b的字串s2若
s1 == s2:- 若
b[0] == a[k]说明必然可以使得a == b - 若
b[0] != a[k],则当k之前存在a[i] == b[0]时可以使得a == b,反之不行
- 若
若
s1 != s2,则无论如何操作都无法使得a == b
代码
#include <bits/stdc++.h>
using namespace std;
void solve(){
int n, m;
cin >> n >> m;
string a, b;
cin >> a >> b;
int k = a.size() - b.size(); //对其的位置
string s1 = a.substr(k + 1,b.size() - 1);
string s2 = b.substr(1,b.size() - 1);
if(s1 == s2){
int flag = 0;
if(a.rfind(b[0], k) != -1) flag = 1;
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
else cout << "NO" << endl;
}
int main(){
int _;
cin >> _;
while(_ --){
solve();
}
// solve();
return 0;
}
B. Luke is a Foodie
题目大意
- 对于 a i a_i ai和固定的 x x x
- 有可以变成任意整数的 v v v,使得 ∣ v − a i ∣ ≤ x |v - a_i|\le x ∣v−ai∣≤x
- 遍历数组 a a a,求 v v v最小变化的次数
思想
- 由 ∣ v − a i ∣ ≤ x |v - a_i|\le x ∣v−ai∣≤x可知 a i − x ≤ v ≤ a i + x a_i - x\le v \le a_i + x ai−x≤v≤ai+x
- 故对于
a[i],必然存在满足 ∣ v − a i ∣ ≤ x |v - a_i|\le x ∣v−ai∣≤x的区间[l,r],l = a[i] - x, r = a[i] + x - 设
a[i + 1]的区间[l',r'],l = a[i + 1] - x, r = a[i + 1] + x - 若
[l,r]与[l',r']有公共区间时,v可以不用发生改变,并将区间更新为其公共区间 - 若
[l,r]与[l',r']无公共区间时,v将发生改变,并将区间变为[l',r'] - 公共区间存在判断:
max(l,l') <= min(r,r')说明存在公共区间
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
void solve(){
LL n, x;
cin >> n >> x;
LL cnt = 0;
LL t;
cin >> t;
LL l = t - x, r = x + t; //初始区间
for(int i = 1; i < n; i ++){
LL y;
cin >> y;
LL p1 = y - x, p2 = y + x;
if(max(p1,l) <= min(p2,r)){
//是否有公共区间
l = max(p1,l); //更新公共区间左边界
r = min(p2,r); //更新公共区间右边界
}
else{
cnt ++; //不存在公共区间,需要变化一次
l = p1; //重置区间
r = p2;
}
}
cout << cnt << endl;
}
int main(){
int _;
cin >> _;
while(_ --){
solve();
}
// solve();
return 0;
}
C. Virus
题目大意
- 1 ∼ N 1\sim N 1∼N的房屋围成一圈
- 给出初始感染病毒的房屋编号
- 每天可选择未感染的房屋进行保护,可使其永久不被感染
- 每天已感染的房屋其左右邻居都会受到感染
- 求最优策略下,最终感染的房屋数量
思想
- 贪心
- 每次选择未感染的最长区间进行保护
- 对于被保护的区间
[l,r]:- 经过第一天:
- 保护
[l,r]的一个端点,设保护a[l] a[l]不会感染,a[r]会被感染- 其他所有未受到保护的区间
[l',r']里,a[l']和a[r']被感染
- 保护
- 经过第二天:
- 保护
[l,r]的另一个端点a[r],由于第一天a[r]被感染,故只能保护a[r - 1] - 其他所有未受到保护的区间
[l',r']里,a[l' + 1]和a[r' - 1]被感染
- 保护
- 即对于选择保护的区间
[l,r],a[r]被感染,我们只能保护到[l,r - 1]这一段,且其余所有未受到保护的区间[l',r']里a[l'],a[r'],a[l' + 1],a[r' - 1]受到感染,感染后的区间变为[l' + 2, r' - 2]
- 经过第一天:
- 综上可知,我们优先保护最长的未被感染的区间,即可实现最优策略
- 由于选择保护的区间端点可以任选,故只需要考虑区间长度,不需要维护额外的信息
- 注意不要忽略首尾相连的区间
代码
#include <bits/stdc++.h>
using namespace std;
void solve(){
int n, m;
cin >> n >> m;
vector<int> vis; //vis存储最先被感染的房屋编号
for(int i = 0; i < m; i ++){
int x;
cin >> x;
vis.push_back(x);
}
sort(vis.begin(),vis.end()); //将编号从小到大排序
priority_queue<int> st; //优先队列维护当前最大长度的区间
st.push(n - vis.back() + vis[0] - 1); //将首尾相连的区间长度加入
for(int i = 0; i + 1 < vis.size(); i ++){
st.push(vis[i + 1] - vis[i] - 1); //将未感染的区间的长度加入
}
int cnt = 0; //存储未感染的区间长度
for(int i = 0; i + 1 > 0; i ++){
//i代表天数
if(!st.empty() && st.top() - i * 4 > 0){
//经过一天,下一个区间长度 -4
int k = st.top() - i * 4; //设k为当前区间经过i天后未感染的区间长度
if(k > 1) k --; //对于一个端点的保护,会使另一个端点被感染(长度-1),若区间长度仅为1,则只能保护1长度
cnt += k; //累计保护到的区间长度
st.pop();
}
else break;
}
cout << n - cnt << endl; //区间总长 - 保护的区间长度 = 被感染的区间长度 = 被感染的房屋数量
}
int main(){
int _;
cin >> _;
while(_ --){
solve();
}
// solve();
return 0;
}
D. Magical Array
题目大意
- 对于一个长度为 m m m的数组 b b b,构造 n n n个与 b b b相同的的数组 c c c
- 对于数组 c t ( 1 ≤ t ≤ n ) c_t(1\le t \le n) ct(1≤t≤n)现有操作:
- 操作1:首先将 c t [ i ] = c t [ i ] − 1 , c t [ j ] = c t [ j ] − 1 c_t[i]=c_t[i]-1,c_t[j]=c_t[j]-1 ct[i]=ct[i]−1,ct[j]=ct[j]−1,然后将 c t [ i − 1 ] = c t [ i − 1 ] + 1 , c t [ j + 1 ] = c t [ j + 1 ] + 1 c_t[i-1]=c_t[i-1]+1,c_t[j+1]=c_t[j+1]+1 ct[i−1]=ct[i−1]+1,ct[j+1]=ct[j+1]+1
- 操作2:首先将 c t [ i ] = c t [ i ] − 1 , c t [ j ] = c t [ j ] − 1 c_t[i]=c_t[i]-1,c_t[j]=c_t[j]-1 ct[i]=ct[i]−1,ct[j]=ct[j]−1,然后将 c t [ i − 1 ] = c t [ i − 1 ] + 1 , c t [ j + 2 ] = c t [ j + 2 ] + 1 c_t[i-1]=c_t[i-1]+1,c_t[j+2]=c_t[j+2]+1 ct[i−1]=ct[i−1]+1,ct[j+2]=ct[j+2]+1
- 选择某一个数 k ( 1 ≤ k ≤ n ) k(1\le k \le n) k(1≤k≤n),使得 c k c_k ck为特别数组
- 非特别数组 c i ( 1 ≤ i ≤ n , i ≠ k ) c_i(1\le i \le n,i \ne k) ci(1≤i≤n,i=k)只能执行操作1若干次
- 特别数组 c k ( 1 ≤ k ≤ n ) c_k(1\le k \le n) ck(1≤k≤n)只能执行操作2若干次
- 给出这些操作后的数组 c c c,找出其中的特别数组的编号 k k k,及其执行了多少次操作2
思想
- 对于 c t ( 1 ≤ t ≤ n ) (一) 对于 c i − 1 , c i , c j , c j + 1 ,可以得到 c i − 1 × ( i − 1 ) + c i × i + c j × j + c j + 1 × ( j + 1 ) 化简得: i × ( c i − 1 + c i ) + j × ( c j + c j + 1 ) − c i − 1 + c j + 1 ① 对于 c i − 1 , c i , c j , c j + 1 执行操作 1 : ( c i − 1 + 1 ) × ( i − 1 ) + ( c i − 1 ) × i + ( c j − 1 ) × j + ( c j + 1 + 1 ) × ( j + 1 ) 化简得: i × ( c i − 1 + c i ) + j × ( c j + c j + 1 ) − c i − 1 + c j + 1 ② 可知① = ②,即操作 1 不会改变 c i × i 的和 (二) 对于 c i − 1 , c i , c j , c j + 1 , c j + 2 , 可以得到 c i − 1 × ( i − 1 ) + c i × i + c j × j + c j + 1 × ( j + 1 ) + c j + 2 × ( j + 2 ) 化简得: i × ( c i − 1 + c i ) + j × ( c j + c j + 1 + c j + 2 ) − c i − 1 + c j + 1 + 2 × c j + 2 ③ 对于 c i − 1 , c i , c j , c j + 1 , c j + 2 执行操作 2 : ( c i − 1 + 1 ) × ( i − 1 ) + ( c i − 1 ) × i + ( c j − 1 ) × j + c j + 1 × ( j + 1 ) + ( c j + 2 + 1 ) × ( j + 2 ) 化简得: i × ( c i − 1 + c i ) + j × ( c j + c j + 1 + c j + 2 ) − c i − 1 + c j + 1 + 2 × c j + 2 + 1 ④ 可知③ = ④ + 1 ,即操作 1 会改变 c i × i 的和,使其加 1 综上可知:对每一个数组 c ,求 S f = ∑ c i × i 与其他数组 c 的 S f 不同的数组即为特别数组,记为 S p 其操作 2 的次数为 S p − S f 对于c_t(1\le t \le n)\\\\ \begin{aligned} (一)\\\\ 对于&c_{i-1},c_i,c_j,c_{j+1},可以得到c_{i−1}×(i−1)+c_i×i+c_j×j+c_{j+1}×(j+1)\\\\ &化简得:i×(c_{i−1}+c_i)+j×(c_j+c_{j+1})−c_{i−1}+c_{j+1}①\\\\ 对于&c_{i-1},c_i,c_j,c_{j+1}执行操作1:\\\\ &(c_{i−1}+1)×(i−1)+(c_i-1)×i+(c_j-1)×j+(c_{j+1}+1)×(j+1)\\\\ &化简得:i×(c_{i−1}+c_i)+j×(c_j+c_{j+1})−c_{i−1}+c_{j+1}②\\\\ &可知①=②,即操作1不会改变c_i\times i的和 \\\\ \end{aligned}\\\\ \begin{aligned} (二)\\\\ 对于&c_{i-1},c_i,c_j,c_{j+1},c_{j+2},可以得到c_{i−1}×(i−1)+c_i×i+c_j×j+c_{j+1}×(j+1)+c_{j+2}\times (j+2)\\\\ &化简得:i×(c_{i−1}+c_i)+j×(c_j+c_{j+1}+c_{j+2})−c_{i−1}+c_{j+1}+2\times c_{j+2}③\\\\ 对于&c_{i-1},c_i,c_j,c_{j+1},c_{j+2}执行操作2:\\\\ &(c_{i−1}+1)×(i−1)+(c_i-1)×i+(c_j-1)×j+c_{j+1}×(j+1)+(c_{j+2}+1)\times (j+2)\\\\ &化简得:i×(c_{i−1}+c_i)+j×(c_j+c_{j+1}+c_{j+2})−c_{i−1}+c_{j+1}+2\times c_{j+2}+1④\\\\ &可知③=④+1,即操作1会改变c_i\times i的和,使其加1\\\\ \end{aligned}\\\\ 综上可知:对每一个数组c,求S_f = \sum c_i\times i\\\\ 与其他数组c的S_f不同的数组即为特别数组,记为S_p\\\\ 其操作2的次数为S_p-S_f\\\\ 对于ct(1≤t≤n)(一)对于对于ci−1,ci,cj,cj+1,可以得到ci−1×(i−1)+ci×i+cj×j+cj+1×(j+1)化简得:i×(ci−1+ci)+j×(cj+cj+1)−ci−1+cj+1①ci−1,ci,cj,cj+1执行操作1:(ci−1+1)×(i−1)+(ci−1)×i+(cj−1)×j+(cj+1+1)×(j+1)化简得:i×(ci−1+ci)+j×(cj+cj+1)−ci−1+cj+1②可知①=②,即操作1不会改变ci×i的和(二)对于对于ci−1,ci,cj,cj+1,cj+2,可以得到ci−1×(i−1)+ci×i+cj×j+cj+1×(j+1)+cj+2×(j+2)化简得:i×(ci−1+ci)+j×(cj+cj+1+cj+2)−ci−1+cj+1+2×cj+2③ci−1,ci,cj,cj+1,cj+2执行操作2:(ci−1+1)×(i−1)+(ci−1)×i+(cj−1)×j+cj+1×(j+1)+(cj+2+1)×(j+2)化简得:i×(ci−1+ci)+j×(cj+cj+1+cj+2)−ci−1+cj+1+2×cj+2+1④可知③=④+1,即操作1会改变ci×i的和,使其加1综上可知:对每一个数组c,求Sf=∑ci×i与其他数组c的Sf不同的数组即为特别数组,记为Sp其操作2的次数为Sp−Sf
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
void solve(){
LL n, m;
cin >> n >> m;
LL S1 = -1, S2 = -1; //S求c_i * i的和
LL cnt1 = 0, cnt2 = 0; //cnt记录S的数量
LL p1, p2; //存储第一次出现S的编号
for(LL i = 1; i <= n; i ++){
LL sum = 0;
for(LL j = 1; j <= m; j ++){
LL x;
cin >> x;
sum += x * j;
}
if(S1 == -1){
S1 = sum;
p1 = i;
}
else if(S1 != -1 && S2 == -1 && S1 != sum){
S2 = sum;
p2 = i;
}
if(S1 == sum) cnt1 ++;
if(S2 == sum) cnt2 ++;
}
if(cnt1 > cnt2){
cout << p2 << " " << S2 - S1 << endl;
}
else cout << p1 << " " << S1 - S2 << endl;
}
int main(){
LL _;
cin >> _;
while(_ --){
solve();
}
// solve();
return 0;
}
后记
A A A题一开始没找到规律,找到规律后居然没有把错思路的代码删掉,狠狠的吃
WA的铁头娃
B B B题读懂题意就很简单了,没什么好说的,就是判断公共区间
C C C题一直在想着怎么维护端点的信息,最后发现根本不需要,只要长度就行了QAQ
D D D题没时间了,太抽象了也看不懂,补题看题解发现证明的想法实在是妙极了,根本想不到
最后还是没能上绿,
我是废物
边栏推荐
- 重装腾讯云云监控后如果对应服务不存在可通过sc.exe命令添加服务
- 632. Minimum interval
- Graphical LeetCode - 1161. Maximum Sum of In-Layer Elements (Difficulty: Moderate)
- JSP out. The write () method has what function?
- NodeJs, all kinds of path
- What does the errorPage attribute of the JSP page directive do?
- IP核:FIFO
- Arduino Basic Syntax
- Redis-消息发布订阅
- 不要用jOOQ串联字符串
猜你喜欢
![[Headline] Written test questions - minimum stack](/img/67/08f2be8afc780e3848371a1b5e04db.png)
[Headline] Written test questions - minimum stack

String splitting function strtok exercise
![[Solution] Emqx startup under win10 reports Unable to load emulator DLL, node.db_role = EMQX_NODE__DB_ROLE = core](/img/c8/d7183330ee86c2cae9c21fecb2805b.png)
[Solution] Emqx startup under win10 reports Unable to load emulator DLL, node.db_role = EMQX_NODE__DB_ROLE = core

如何发现新的潜力项目?工具推荐

Redis-消息发布订阅

146. LRU cache

Graphical LeetCode - 1161. Maximum Sum of In-Layer Elements (Difficulty: Moderate)

632. Minimum interval

Redis的集群模式

Realize deletion - a specified letter in a string, such as: the string "abcd", delete the "a" letter in it, the remaining "bcd", you can also pass multiple characters to be deleted, and pass "ab" can
随机推荐
当奈飞的NFT忘记了Web2的业务安全
Disk and file system management
含外部储能的电力系统暂态稳定分布式控制
短视频SEO搜索运营获客系统功能介绍
ROS 动态参数
How to use the go language standard library fmt package
【21天学习挑战赛】顺序查找和二分查找的小总结
Trie详解
JSP how to obtain the path information in the request object?
Constructor, this keyword, method overloading, local variables and member variables
实现删除-一个字符串中的指定字母,如:字符串“abcd”,删除其中的”a”字母,剩余”bcd”,也可以传递多个需要删除的字符,传递”ab”也可以做到删除”ab”,剩余”cd”。
Multidimensional Correlation Time Series Modeling Method Based on Screening Partial Least Squares Regression of Correlation Variables
众筹DAO“枯萎”的缩影:曾拍下《沙丘》未出版手稿的Spice DAO解散
Day11 shell脚本基础知识
Microsoft PC Manager V2.1 beta version officially released
Simpson's paradox
BGP first experiment
Graphical LeetCode - 1161. Maximum Sum of In-Layer Elements (Difficulty: Moderate)
IO流基础
BGP 第一次实验