2019 ACM训练计划——( 每天5题 ) 训练计划12

本文解析了Codeforces Round #590(Div.3)的四道算法题,包括价格统一问题、社交网络消息处理、字符查询问题及可乐排队问题,提供了详细的解题思路与代码实现。

A

Codeforces Round #590 (Div. 3), problem: (A) Equalize Prices Again,


题目大意

为了省去记住价格的麻烦,将所有物品的价格进行统一,然后要我们找出最小的那个价格,使得卖完当前所有物品的价值总和要大于等于原来的价值总和


题解

直接用总和除以物品总数即可,不过我们需要向上取整一下

拓展一下新的取整函数
floor()是向负无穷大舍入,floor(-10.5) == -11;
ceil()是向正无穷大舍入,ceil(-10.5) == -10

#include<bits/stdc++.h>
using namespace std;
int t,n;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        int x;
        int ans=n-1;
        for(int i=1;i<=n;i++){
            cin>>x;
            ans+=x;
        }
        cout<<ans/n<<endl;
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
int t,n;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        int x;
        int ans=0;
        for(int i=1;i<=n;i++){
            cin>>x;
            ans+=x;
        }
        cout<<(int)ceil(ans*1.0/n)<<endl;
    }
    return 0;
}

B

Codeforces Round #590 (Div. 3), problem: (B1) Social Network (easy version)


题目大意

由于只是数据范围不同,直接见后面C题解析即可


题解

详情见CCCCCC

C

Codeforces Round #590 (Div. 3), problem: (B2) Social Network (hard version)


题目大意

大概讲的是,给你n个消息,然后只有k个格子装,如果格子不存在当前的消息,就把消息放进去,不过要注意格子是有大小的,如果超过大小,就要删除最开始的那条信息,以此类推模拟即可


题解

模拟题,我们可以采用双向队列来做,然后用map维护一下。

我一开始用了一个vis数组来维护的,然后炸掉了,数组范围不够什么的,后面改用map来做就okk了

其实一开始我知道这题双向队列的话会很舒服,但是我想尝试下用map做,然后又考虑map默认key值排序,后面又采用unordered_map尝试了下,发现没有我想象中那么好理解,后面还是老老实实用了双向队列做了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e8+10;
int n,k,x;
deque<int> dq;
map<int,bool> vis;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    for(int i=0;i<n;i++){
        cin>>x;
        if(dq.size()<k){
            if(!vis[x]){
                vis[x]=true;
                dq.push_front(x);
            }
        }
        else{
            if(!vis[x]){
                vis[x]=true;
                dq.push_front(x);
                vis[dq.back()]=false;
                dq.pop_back();
            }
        }
    }
    cout<<dq.size()<<endl;
    while(!dq.empty()){
        cout<<dq.front()<<" ";
        dq.pop_front();
    }
    return 0;
}

D

Codeforces Round #590 (Div. 3), problem: (D) Distinct Characters Queries


题目大意

线段树单点修改区间查询


题解

线段树单点修改区间查询

线段树维护二进制,将查询的字母区间内的字母转化为二进制下,合并区间就是与操作,最后我们看我们所查询得到的二进制有几个1即可

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
char s[maxn];
int tree[maxn*4];
int n,q;

inline void PushUp(int rt){
    tree[rt]=tree[rt<<1] | tree[rt<<1|1];
}

void build(int rt,int le,int re){
    if(le==re){
        tree[rt]=1<<(s[le]-'a');
        return;
    }
    int mid=(le+re)/2;
    build(rt<<1,le,mid);
    build(rt<<1|1,mid+1,re);
    PushUp(rt);
}

void Update(int rt,int le,int re,int p,int c){
    if(le==re){
        tree[rt]=1<<c;
        return;
    }
    int mid=(le+re)/2;
    if(p<=mid)
        Update(rt<<1,le,mid,p,c);
    else
        Update(rt<<1|1,mid+1,re,p,c);
    PushUp(rt);
}

int Query(int rt,int le,int re,int ql,int qr){
    if(qr<le||ql>re)
        return 0;
    if(ql<=le&&qr>=re)
        return tree[rt];
    int mid=(le+re)/2;
    int res=0;
    res |=Query(rt<<1,le,mid,ql,qr);
    res |=Query(rt<<1|1,mid+1,re,ql,qr);
    return res;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>s+1;
    n=strlen(s+1);
    build(1,1,n);
    cin>>q;
    int op,le,re;
    char va;
    while(q--){
        cin>>op;
        if(op==1){
           cin>>le>>va;
           Update(1,1,n,le,va-'a');
        }
        else{
            cin>>le>>re;
            int res=Query(1,1,n,le,re);
            int cnt=0;
            while(res){
                if(res&1)
                    cnt++;
                res>>=1;
            }
            cout<<cnt<<endl;
        }
    }
    return 0;
}

E

Qualification 2, problem: (A) Double Cola


题目大意

五个人排队喝可乐,一个人喝完一杯,就在可乐的最后面放两杯自己喝的可乐,问第n个喝的人是谁


题解

#include<bits/stdc++.h>
using namespace std;
string s[6]={"0","Sheldon", "Leonard", "Penny", "Rajesh", "Howard" };
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    while(n>5){
        n=(n-4)/2;
    }
    cout<<s[n]<<endl;
    return 0;
}
学如逆水行舟,不进则退
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一百个Chocolate

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值