Codeforces Round 980 (Div. 2)
Codeforces Round 980 (Div. 2) 总结
A
简单小学算数题。
- 如果
,直接输出 。 - 否则,列方程
, ,输出 ,即 。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int N=1;
int a,b;
void solve()
{
cin>>a>>b;
if(a>=b) cout<<a<<'\n';
else cout<<max(2*a-b,0)<<'\n';
}
int main ()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--) solve();
return 0;
}
B
这道题似乎卡了不少人 qwq。首先,因为每次不知道是不是有一个按钮按完后不出饮料,额外的贡献就产生在这,但是同一个不出的按钮又只会按一次(又不是傻子)。
所以不妨将
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int n;
ll k,ans;
ll a[N];
void solve()
{
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
ans=0;
for(int i=1;i<=n;i++)
{
ll t=(a[i]-a[i-1])*(n-i+1);
ans++;
if(k<=t)
{
ans+=k;
break;
}
else
{
k-=t;
ans+=t;
}
}
cout<<ans-1<<'\n';
}
int main ()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}
C
其实题意就是设计一种 pair
的排序。
严格证明还是要分类讨论:设数对中的最大值为
,显然 应该在前面。 ,分析一下可知谁前谁后都一样,看作一个整体,也不会影响其他的数对的排序。
因此只需要按最小值为第一关键字,最大值为第二关键字(当然反一下也可以)排序即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct node
{
int x,y;
int mi,mx;
friend bool operator < (const node &a,const node &b)
{
if(a.mx==b.mx) return a.mi<b.mi;
else return a.mx<b.mx;
}
}a[N];
int n;
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
a[i].x=x,a[i].y=y;
a[i].mi=min(x,y),a[i].mx=max(x,y);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) cout<<a[i].x<<' '<<a[i].y<<' ';
cout<<'\n';
}
int main ()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}
D
比较巧妙的思路。
首先肯定是要尽可能地跳到下标更大的位置,然后再拿前面能拿的所有分。但是因为
考虑建图,跳的过程有两种情况:
- 不跳过,从
到 ,没有亏损。 - 跳过,从
跳到 ,要亏损 的分数。
这样的话跑一遍最短路,枚举一下终点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<ll,int> PLI;
const int N=4e5+5,M=N*2;
int n;
ll a[N],b[N];
int e[M],w[M],ne[M],h[N],tot;
void add(int x,int y,int z)
{
e[++tot]=y,w[tot]=z,ne[tot]=h[x],h[x]=tot;
}
bool vis[N];
ll dis[N];
priority_queue<PLI> q;
void dijkstra()
{
for(int i=1;i<=n;i++) vis[i]=0,dis[i]=1e18;
dis[1]=0;
q.push({0,1});
while(q.size())
{
int x=q.top().second;q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=h[x];i;i=ne[i])
{
int y=e[i],z=w[i];
if(dis[y]>dis[x]+z)
{
dis[y]=dis[x]+z;
q.push({-dis[y],y});
}
}
}
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++) h[i]=0;
tot=0;
for(int i=1;i<=n;i++)
{
if(i!=1) add(i,i-1,0);
add(i,b[i],a[i]);
}
dijkstra();
ll ans=0,sum=0;
for(int i=1;i<=n;i++)
{
sum+=a[i];
ans=max(ans,sum-dis[i]);
}
cout<<ans<<'\n';
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}
分类:
codeforces总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」