Codeforces Round 980 (Div. 2)(A-D)

感觉这场都是猜,补了个D

A - Profitable Interest Rate

思路 

给定a和b,一次a减去1,b减去2,问什么时候,a>b

实际上就是a-x>=b-2x,也就是x>=b-a

代码

void solve() {
    int a, b;
    cin >> a >> b;
    // a-x>=b-2*x
    // x>=b-a;
    ll x=b-a;
    if(b<=a){
        cout<<a;
        return;
    }
    ll c = 0;
    cout << max(c, a-(b - a));
}

 B- Buying Lemonade

思路

通过他给的案例我们会发现,实际上就是从1到n开始点击,一遍一遍的循环,如果当前点点击了一下没有之后就不点击了,那么排序之后从小的开始点击,知道点击到>=k为止 

 代码

void solve() {
    ll n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
        arr[i];
    }
    sort(arr + 1, arr + 1 + n);
    ll sum=0;
    for(int i=1;i<=n;i++){
        if(sum+arr[i]*(n-i+1)>=k){
            cout<<i-1+k;
            return;
        }
        sum=sum+arr[i];
    }
}

C - Concatenation of Arrays 

思路 

其实不是很会猜的,按样例跑一边,发现是和的小的在前面,就结束了,证明可以看官网的题解 

代码

struct node {
    ll x, y;
};
node arr[200020];
bool cmp(node a, node b) {
    if(a.x+a.y!=b.x+b.y){
        return a.x+a.y<b.x+b.y;
    }
    if (a.x != b.x) {
        return a.x < b.x;
    }
    return a.y < b.y;
}
void solve() {
    ll n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i].x >> arr[i].y;
    }
    sort(arr + 1, arr + 1 + n, cmp);
    for (int i = 1; i <= n; i++) {
        cout << arr[i].x << " " << arr[i].y << ' ';
    }
}

 D - Skipping

思路 

赛时想用dp写的,发现一直不对,发现最短路,我们发现,如果从i到b[i]需要代价为a[i],所以我们会发现,从点i到i-1放一条边权为0的有向路,那么i到b[i]需要的是价值为a[i]的边权路,求最短路即可

代码

struct edge {
    int v, w;
};
struct node {
    int dis, u;
    bool operator>(const node& a) const { 
        return dis > a.dis;
    }
};
const int MAXN = 4e5+2;
vector<edge> e[MAXN];
int dis[MAXN], vis[MAXN];
priority_queue<node, vector<node>, greater<node>> q;
 
void dijkstra(int n, int s) {
    memset(dis, 0x3f, (n + 1) * sizeof(int));
    dis[s] = 0;
    q.push({ 0, s });
    while (!q.empty()) {
        int u = q.top().u;
        q.pop();
        if (vis[u]) {
            continue;
        }
        vis[u] = 1;
        for (auto ed : e[u]) {
            int v = ed.v, w = ed.w;
            if (dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;
                q.push({ dis[v], v });
            }
        }
    }
}
void solve() {
    ll n;
    cin >> n;
    vector<ll>arr(n + 2);
    vector<ll>brr(n + 2);
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
        vis[i] = 0;
        e[i].clear();
    }
    for (int i = 1; i <= n; i++) {
        cin >> brr[i];
        e[i].push_back({ i - 1,0 });
        e[i].push_back({ brr[i],arr[i] });
    }
    dijkstra(n, 1);
    /*for (int i = 1; i <= n; i++) {
        cout << dis[i] << " ";
    }*/
    ll ans = 0;
    ll sum = 0;
    for (int i = 1; i <= n; i++) {
        sum = sum + arr[i];
        if (dis[i] != 0x3f) {
            ans = max(ans, sum - dis[i]);
        }
    }
    cout << ans;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值