Codeforces Round 980 (Div. 2)

Codeforces Round 980 (Div. 2) 总结

A

简单小学算数题。

  • 如果 ba,直接输出 a
  • 否则,列方程 ax=b2xx=ba,输出 ax,即 2ab
#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。首先,因为每次不知道是不是有一个按钮按完后不出饮料,额外的贡献就产生在这,但是同一个不出的按钮又只会按一次(又不是傻子)。
所以不妨将 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=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 的排序。
严格证明还是要分类讨论:设数对中的最大值为 mx,最小值为 mi,对于两个数对 x,y

  • xmiymixmxymx,显然 x 应该在前面。
  • xmiymiymxxmx,分析一下可知谁前谁后都一样,看作一个整体,也不会影响其他的数对的排序。

因此只需要按最小值为第一关键字,最大值为第二关键字(当然反一下也可以)排序即可。

#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

比较巧妙的思路。

首先肯定是要尽可能地跳到下标更大的位置,然后再拿前面能拿的所有分。但是因为 b 的存在这不太好直接实现。
考虑建图,跳的过程有两种情况:

  • 不跳过,从 ii1,没有亏损。
  • 跳过,从 i 跳到 bi,要亏损 ai的分数。

这样的话跑一遍最短路,枚举一下终点 ians=preidisi

#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;
}

posted @   zhouruoheng  阅读(26)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示