目录
A. Maximum Cake Tastiness
- 题意:
给定一段序列,长度为n:
定义这个序列的值为:
你可以进行一次操作,选择区间[ l , r ],并翻转区间内的数,使得序列的值最大。
- 思路:
找到序列中第二大的数,将它翻转到最大的数旁即可。
即答案就是序列中最大数和次大数的和。
- 时间复杂度:
O(n)
- AC代码:
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5+10,M = N * 2,INF = 0x3f3f3f3f,P = 9901;
void solve()
{
int maxn1 = -1,maxn2 = -1;
int n;
std::cin>>n;
for(int i = 1 ; i <= n ; i++)
{
int x;
std::cin>>x;
if(x > maxn1)std::swap(maxn1,x);
if(x > maxn2)std::swap(maxn2,x);
}
std::cout<<maxn1+maxn2<<'\n';
}
int main()
{
std::ios::sync_with_stdio(false);
int T;
std::cin>>T;
while(T--)
{
solve();
}
return 0;
}
B. Prefix Removals
- 题意:
给定一个字符串S,你可以进行如下操作:
选择字符串S的一个前缀,如果这个前缀在
中出现,则可以把这个前缀删除
输出进行这个操作若干次以后的最终字符串(即最短字符串)
- 思路
我们每次都选择长度为1的前缀(即第一个字母)
那么如果后面存在这个字母,显然这个字母是可以是删除的
如果后面不存在这个字母,那么操作结束
易证明这样删除可以得到最短字符串
- 时间复杂度
O(n)
- AC代码:
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5+10,M = N * 2,INF = 0x3f3f3f3f,P = 9901;
int cnt[30];
void solve()
{
memset(cnt,0,sizeof cnt);
std::string s;
std::cin>>s;
for(int i = 0 ; i < s.size() ; i++)cnt[s[i] - 'a']++;
for(int i = 0 ; i < s.size() ; i++)
{
if(cnt[s[i]-'a']==1)
{
for(int j = i ; j < s.size() ; j++)
std::cout<<s[j];
std::cout<<'\n';
return;
}
cnt[s[i]-'a']--;
}
}
int main()
{
std::ios::sync_with_stdio(false);
int T;
std::cin>>T;
while(T--)
{
solve();
}
return 0;
}
C. Alice and the Cake
- 题意:
给定一个初始数w (w >= 2) ,
现将这个数分成两个部分:
w 为 奇数:w/2 , w/2+1(整数除法)
w 为 偶数: w/2 , w/2
可以对拆分完后的数进行继续拆分。
现给出最终拆分后的一个序列:
询问原始数 w ,是否存在拆分方案产生给出的序列。
- 思路:
显然初始数 w 为序列的和
我们去模拟拆分过程,把拆分过程中产生的数放入一个优先队列 B 。
在此之前,把序列 a 也放入一个优先队列 A (multiset也可以)。
我们先把 w 放入优先队列
然后重复一下步骤:
- 从B中取出最大数(即top)
- 与A中最大数比较,若两数相等,则把两数删除
- 若不相等,则把B进行拆分后放入优先队列B
特别的:
- 若在比较过程中 B的最大数 < A的最大数,显然为NO
最终:
- 若两个优先队列均为空,则为YES,否则为NO
- 时间复杂度 :
这里稍微分析一下:
因为优先队列的push操作也是log的,所以时间复杂度要乘上一个log
AC代码:
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5+10,M = N * 2,INF = 0x3f3f3f3f,P = 9901;
void solve()
{
std::priority_queue<ll> que_a,que_b;
int n;
std::cin>>n;
ll sum = 0;
for(int i = 1 ; i <= n ; i++)
{
ll x;
std::cin>>x;
sum += x;
que_a.push(x);
}
que_b.push(sum);
while(!que_b.empty())
{
ll temp = que_b.top();
que_b.pop();
if(temp!=que_a.top()&&temp!=1)
{
que_b.push(temp/2);
que_b.push(temp - temp/2);
}else if(temp==que_a.top())
{
que_a.pop();
}
if(que_a.top() > que_b.top())
{
std::cout<<"NO\n";
return;
}
}
std::cout<<"YES\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int T;
std::cin>>T;
while(T--)
{
solve();
}
return 0;
}
越来越菜了呜呜qwq,用multiset写挂了