Educational Codeforces Round 172 (Rated for Div. 2)题解记录(A~D)
比赛链接:https://codeforces.com/contest/2042
这场爆了,卡死在C题了,QWQ.卡题得跳题啊!!!
A.Greedy Monocarp
题面:
有
在你向箱子中添加硬币后,贪婪的 Monocarp 来了,他想要这些硬币。他会一个接一个地拿走箱子,由于他很贪婪,他总是会选择硬币最多的箱子。当 Monocarp 拿走的箱子中的硬币总数 至少为
你希望 Monocarp 拿走尽可能少的硬币,因此你需要以这样的方式向箱子中添加硬币:当 Monocarp 停止拿走箱子时,他将拥有 恰好
输入:
有
第一行包含两个整数
第二行包含
对于每个测试用例,计算需要添加的最小硬币数,使得 Monocarp 拿走的箱子中的硬币总数恰好为
输出:
对于每个测试用例,打印一个整数 —— 你需要添加的最小硬币数,以便当 Monocarp 停止拿箱子时,他恰好拥有
样例:
4
5 4
4 1 2 3 2
5 10
4 1 2 3 2
2 10
1 1
3 8
3 3 3
————————
0
1
8
2
思路:发现
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[250000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n,m;
cin>>n>>m;
for(ll i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
ll sum=0;
ll ans=0;
for(ll i=n;i>=1;i--)
{
if(sum+a[i]<=m)
sum+=a[i];
else
{
ans=m-sum;
break;
}
}
if(ans==0&&sum<=m)ans=m-sum;
cout<<ans<<endl;
}
return 0;
}
B.Game with Colored Marbles
题面:
Alice 和 Bob 玩一个游戏。有
在他们的回合中,玩家 必须 从剩下的弹珠中拿走 一个 并将其从游戏中移除。如果没有弹珠剩下(所有的
游戏结束时,Alice 的得分计算如下:
她为每个颜色
此外,如果她拿走了所有颜色
例如,假设有
Alice 想要在游戏结束时最大化她的得分。Bob 想要最小化它。两个玩家都以最优的方式进行游戏(即 Alice 选择一个策略,允许她获得尽可能多的分数,而 Bob 选择一个策略,最小化 Alice 可以获得的分数)。
计算游戏结束时 Alice 的得分。
输入:
第一行包含一个整数
每个测试用例由两行组成:
第一行包含一个整数
第二行包含
额外的输入约束:所有测试用例中
输出:
对于每个测试用例,打印一个整数 —— 假设两个玩家都以最优策略进行游戏,Alice 在游戏结束时的得分。
样例:
3
5
1 3 1 3 4
3
1 2 3
4
4 4 4 4
————————
4
4
1
思路:首先对于Alice,她优先拿只有一个的数是最好的,对于Bob也是同理,不妨计这类数的个数为cnt,然后对于存在个数大于等于2的其他数,显然不论Alice先后手,她都一定能有一个,不妨即为cn,所以最后答案为(cnt+1)/2*2+cn.这里直接用了优先队列写
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[250000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
map<ll,ll>q;
set<ll>f;
for(ll i=1;i<=n;i++)
{
ll x;
cin>>x;
q[x]++;
f.insert(x);
}
priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>>op;
for(auto j:f)
{
op.push({q[j],j});
}
map<ll,ll>c;
ll j=0;
ll ans=0;
while(!op.empty())
{
if(j==0)
{
if(op.top().first==1)
{
ans+=2;
j=1;
}
else if(op.top().first%2==0)
{
j=0;
ans++;
}
else
{
j=1;
ans++;
}
op.pop();
}
else
{
if(op.top().first==1)
{
j=0;
}
else if(op.top().first%2==0)
{
j=1;
ans++;
}
else
{
j=0;
ans++;
}
op.pop();
}
}
cout<<ans<<endl;
}
return 0;
}
C.Competitive Fishing
题面:
Alice 和 Bob 参加了一个钓鱼比赛!总共钓到了
他们的表现将根据以下方式评估。首先,选择一个整数
然后,将根据组索引为每条鱼分配一个值:第一组的每条鱼获得等于
每个参赛者的分数仅仅是参赛者钓到的所有鱼的总价值。
你希望 Bob 的分数至少超过 Alice 的分数
输入:
第一行包含一个整数
每个测试用例的第一行包含两个整数
每个测试用例的第二行包含一个字符串,由恰好
额外的输入约束:所有测试用例中
输出:
对于每个测试用例,打印一个整数 —— 你必须将鱼分成的组数的最小值;如果不可能,则打印 -1。
样例:
7
4 1
1001
4 1
1010
4 1
0110
4 2
0110
6 3
001110
10 20
1111111111
5 11
11111
——————————
2
-1
2
-1
3
4
-1
思路:令人痛心棘手的题,这里如果往二分想了就G了。这里证明下二分错误性!,如果假设二分区间个数越多,值越大,你就会发现如果最后一个为0,他其实被前面一点的1抵消更优,而你二分区间越小,值越大,只有一个区间时,答案为0,也不对,故这题二分不对。其实这种题应该用一种方法解决,自己总结为层次拆分法。显然发现增加一个断点,右边区间的值会再之前的基础上变大1.这就可以发现,如果我把每次操作视作增加一条从右端点连的线(选一个没选过的点作为后缀合左端点),如下图,就会发现你所有操作最后就是要形成这种图。既然我要形成这种图,而且我还优先满足k,那为什么不先选后缀合大的地方。于是直接求个后缀和,然后出了第一个点,其他排个序,每次贪心选最大的就好了。
例如
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll pre[250000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n,k;
cin>>n>>k;
string f;
cin>>f;
pre[f.size()]=0;
ll ans=1;
for(ll i=f.size()-1;i>=0;i--)
{
pre[i]=pre[i+1]+(f[i]=='0'?-1:1);
}
if(k==0)
{
cout<<1<<endl;
continue;
}
if(n!=1)
{
sort(pre+1,pre+n);
for(ll i=n-1;i>=1;i--)
{
if(k<=0)
break;
k-=pre[i],ans++;
}
}
if(k>0)cout<<-1<<endl;
else cout<<ans<<endl;
}
return 0;
}
D. Recommendations
题面:
假设你在某个音频流媒体服务工作。该服务有
曲目编号从
如果第
另外,如果一首曲目尚未被第
计算每个用户
输入:
第一行包含一个整数
每个测试用例的第一行包含一个整数
接下来的
额外的输入约束:所有测试用例中
输出:
对于每个测试用例,打印
样例:
4
3
3 8
2 5
4 5
2
42 42
1 1000000000
3
42 42
1 1000000000
42 42
6
1 10
3 10
3 7
5 7
4 4
1 2
——————
0
0
1
999999999
0
0
0
0
0
2
3
2
4
8
思路:题目意思其实是求一个用户被其他用户完全包围的范围最小交区间的长度-用户本身范围的长度。不妨想想对于一个用户(l1,r1)来讲,如果所有区间(设为l,r)l小于他的都已经选出来了,那么此时我就只要去找到这些用户中r大于r1的最大l(
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
// const ll p=rnd()%mod;
const ll maxn=2e5+15;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l,r,v;
}p[maxn<<2];
void build(ll i,ll l,ll r)
{
p[i].l=l,p[i].r=r;
p[i].v=0;
if(l==r)
return ;
build(i<<1,l,(l+r)>>1);
build(i<<1|1,(l+r>>1)+1,r);
}
void xg(ll i,ll l,ll r,ll v)
{
if(p[i].l==l&&p[i].r==r)
{
p[i].v=max(v,p[i].v);
return ;
}
ll mid=(p[i].l+p[i].r)>>1;
if(l<=mid)
xg(i<<1,l,min(mid,r),v);
if(r>=mid+1)
xg(i<<1|1,max(mid+1,l),r,v);
p[i].v=max(p[i<<1].v,p[i<<1|1].v);
}
ll q(ll i,ll l,ll r)
{
ll ans=0;
if(p[i].l==l&&p[i].r==r)
{
ans=p[i].v;
return ans;
}
ll mid=(p[i].l+p[i].r)>>1;
if(l<=mid)
ans=max(ans,q(i<<1,l,min(mid,r)));
if(r>=mid+1)
ans=max(ans,q(i<<1|1,max(mid+1,l),r));
return ans;
}
struct f1
{
ll z,id;
};
vector<f1>g[250000];
ll ans[250000];
bool zm(f1 x,f1 y)
{
return x.z>y.z;
}
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll uop=0;
set<ll>l,r;
map<ll,ll>mp,mp1;
ll n;
cin>>n;
ll ko=0;
for(ll i=1;i<=n;i++)
{
ll x,y;
cin>>x>>y;
l.insert(x);
if(mp1[x]==0)
{
ko++;
mp1[x]=ko;
g[ko].clear();
}
g[mp1[x]].push_back({y,i});
r.insert(y);
}
for(auto j:l)
{
sort(g[mp1[j]].begin(),g[mp1[j]].end(),zm);
}
ll cnt=0;
for(auto j:r)
{
cnt++;
mp[j]=cnt;
}
build(1,1,cnt);
//xg(1,2,2,2);
//cout<<q(1,1,2)<<endl;
r.clear();
map<ll,ll>mu;
for(auto j:l)
{
mu.clear();
ll u=mp1[j];
for(auto z:g[u])
{
auto d=r.lower_bound(z.z);
if(mu[z.z]>0)
{
ans[mu[z.z]]=0;
ans[z.id]=0;
}
else
{
if(d==r.end())
{
ans[z.id]=0;
}
else
{
ll k=q(1,mp[*d],cnt);
ans[z.id]=j-k+*d-z.z;
}
}
mu[z.z]=z.id;
xg(1,mp[z.z],mp[z.z],j);
r.insert(z.z);
}
}
for(ll i=1;i<=n;i++)
cout<<ans[i]<<endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现