首页 > 其他分享 >Codeforces Round 946 (Div. 3)

Codeforces Round 946 (Div. 3)

时间:2024-05-21 11:41:23浏览次数:24  
标签:idx 946 auto Codeforces ++ int mp2 mp Div

Codeforces Round 946 (Div. 3)

总结:赛时状态很好,做出了感觉平常会赛时寄掉但是赛后补题的E,但是也因此花费时间太多,没时间去做更简单的F和G,赛后G用时十分钟AC,F码的有点麻烦,用时40分钟左右,感觉三个小时能AK?

A. Phone Desktop

题意:给定3*5的平面,有a个1*1的格子和b个2*2的格子,求完全放下所有的格子最少需要几面平面

思路:首先想到一面平面最多放两个2*2的格子,所以先求放下所有2*2格子所需要的平面,然后算一下剩余的1*1的空格数量,如果小于b就添加新的平面、

void solve(){
    int x, y;
    cin >> x >> y;
    int ans = y / 2 + y % 2;
    int kong = y / 2 * 7;
    if(y % 2){
        kong += 15 - 4;
    }
    if(kong < x){
        ans += (x - kong) / 15 + ((x - kong) % 15 != 0);
    }
    cout << ans << '\n';
}

B. Symmetric Encoding

题意:给定字符串,按照出现过的字母的字典序排序来反向对应,比如如果字符串是aadccef,那么出现过的字母就是acdef,反过来就是fedca,所有a换成f,c换成e,以此类推

思路:读懂即可做

void solve(){
    int n;
    string s;
    cin >> n >> s;
    map<char, int> mp;
    vector<char> v;
    for(int i = 0; i < n; i ++){
        if(!mp[s[i]]){
            mp[s[i]] = 1;
            v.push_back(s[i]);
        }
    } 
    sort(v.begin(), v.end());
    auto v1 = v;
    sort(v1.begin(), v1.end(), greater<char>());
    map<char, char> ans;
    for(int i = 0; i < v.size(); i ++){
        ans[v[i]] = v1[i];
    }
    for(int i = 0; i < n; i ++){
        cout << ans[s[i]];
    }
    

C. Beautiful Triple Pairs

题意:定义一对优美三元组为存在且仅存在一对对应的字母不相同,求有多少个优美三元组

思路:枚举哪一位不同即可,另外两位都相同,实现起来比较抽象

void solve(){
    int n;
    cin >> n;
    vector<ll> a(n + 1);
    for(int i = 1; i <= n; i ++) cin >> a[i];
    map<PII, map<int, int>> mp1, mp2, mp3;
    map<PII, int> sum1, sum2, sum3;
    for(int i = 3; i <= n; i ++){
        mp1[{a[i - 2], a[i - 1]}][a[i]] ++;
        sum1[{a[i - 2], a[i - 1]}] ++;
        
        mp2[{a[i - 2], a[i]}][a[i - 1]] ++;
        sum2[{a[i - 2], a[i]}] ++;
        
        mp3[{a[i - 1], a[i]}][a[i - 2]] ++;
        sum3[{a[i - 1], a[i]}] ++;        
    }
    int ans = 0;
    for(auto [x, y] : mp1){
        auto [i, j] = x;
        int sum = sum1[x], res = 0;
        for(auto [x1, y1] : y){
            res += (sum - y1) * y1;
        }
        ans += res / 2;
    }
    
    for(auto [x, y] : mp2){
        auto [i, j] = x;
        int sum = sum2[x], res = 0;
        for(auto [x1, y1] : y){
            res += (sum - y1) * y1;
        }
        ans += res / 2;
    }
    
    for(auto [x, y] : mp3){
        auto [i, j] = x;
        int sum = sum3[x], res = 0;
        for(auto [x1, y1] : y){
            res += (sum - y1) * y1;
        }
        ans += res / 2;
    }        
    cout << ans << '\n';
}

D. Ingenuity-2

题意:有上下左右四种指令,每个机器至少执行一次指令,分配指令让两个机器行动结束后在同一地点,且二者至少执行一次指令,求一种分配方案

思路:分类讨论,如果所有指令的个数全是偶数那各一半即可,如果有奇数,就看上下/左右是不是都是奇数,若果是那就可以相互抵消,否则做不到在同一终点,要注意二者必须至少执行一次指令

void solve(){
    int n;
    string s;
    cin >> n >> s;
    vector<int> idx(6);
    for(auto c : s){
        if(c == 'N') idx[1] ++;//右 
        if(c == 'S') idx[2] ++;//左 
        if(c == 'E') idx[3] ++;//上 
        if(c == 'W') idx[4] ++;//下 
    }
    map<int, int> a, b;
    if(idx[1] % 2 == 0 && idx[2] % 2 == 0){
        a[1] = b[1] = idx[1] / 2;
        a[2] = b[2] = idx[2] / 2;
    }
    else if(idx[1] % 2 == 1 && idx[2] % 2 == 1){
        idx[1] --;
        idx[2] --;
        a[1] ++;
        a[2] ++;
        a[1] += idx[1] / 2;
        b[1] += idx[1] / 2;
        a[2] += idx[2] / 2;
        b[2] += idx[2] / 2;        
    }
    else{
        cout << "NO\n";
        return;
    }
    
    if(idx[3] % 2 == 0 && idx[4] % 2 == 0){
        a[3] = b[3] = idx[3] / 2;
        a[4] = b[4] = idx[4] / 2;
    }
    else if(idx[3] % 2 == 1 && idx[4] % 2 == 1){
        idx[3] --;
        idx[4] --;
        b[3] ++;
        b[4] ++;
        a[3] += idx[3] / 2;
        b[3] += idx[3] / 2;
        a[4] += idx[4] / 2;
        b[4] += idx[4] / 2;        
    }
    else{
        cout << "NO\n";
        return;
    }    
    if(a[1] + a[2] + a[3] + a[4] == 0 || b[1] + b[2] + b[3] + b[4] == 0){
        cout << "NO\n";
        return;        
    }
    for(auto c : s){
        int u = 0;
        if(c == 'N') u = 1;//右 
        if(c == 'S') u = 2;//左 
        if(c == 'E') u = 3;//上 
        if(c == 'W') u = 4;//下
        if(a[u]){
            a[u] --;
            cout << 'R';
        }         
        else{
            b[u] --;
            cout << 'H';
        }
    }
    cout << '\n';
}

E. Money Buys Happiness

题意:给定n个物品,该物品只能在第 i 月购买,花费 hi 获得 ci 的幸福感,只有在每个月的月底可以获得 x 元,求能获得的最大幸福感

思路:体重的 hi 总和不超过 1e5 就是一个提示,定义dp[i][j] 为前 i 个物品获得 j 幸福感的最大剩余钱数,那么转移就是

最后找一下剩余钱数不为0的最大价值即可

void solve(){
    int n, x, sum = 0;
    cin >> n >> x;
    vector<int> c(n + 1), h(n + 1);
    for(int i = 1; i <= n; i ++){
        cin >> c[i] >> h[i];
        sum += h[i];
    } 
    vector<vector<int>> dp(n + 10, vector<int>(sum + 10, -1));
    if(c[1] == 0){
        dp[1][h[1]] = x;
    }
    dp[1][0] = x;
    
    for(int i = 1; i <= sum; i ++) dp[0][i] = 0;
    
    for(int i = 2; i <= n; i ++){
        for(int j = 0; j <= sum; j ++){
            if(dp[i - 1][j] != -1){
                dp[i][j] = max(dp[i][j], dp[i - 1][j] + x);
            }
            if(dp[i - 1][j] >= c[i]){
                dp[i][j + h[i]] = max(dp[i][j + h[i]], dp[i - 1][j] - c[i] + x);
            }
        }
    }
    for(int i = sum; i >= 0; i --){
        if(dp[n][i] != -1){
            cout << i << '\n';
            return;
        }
    }
}

F. Cutting Game

题意:给定a*b的格子,每次会给命令删去前k或者后 k 行/列,并且获得其中的所有有价值的点,轮流操作求各自获得的价值

思路:用两个map分别用x和y排序,然后从前/后删点,并且再开一个map存点是否存在,每次不存在就加上

void solve(){
    ll a, b, n, m;
    cin >> a >> b >> n >> m;
    map<PII, ll> mp1, mp2, mp;
    for(int i = 1; i <= n; i ++){
        ll x, y;
        cin >> x >> y;
        mp1[{x, y}] ++;
        mp2[{y, x}] ++;
        mp[{x, y}] ++;
    }
    
    ll ans1 = 0, ans2 = 0;
    int u = 1, d = a, l = 1, r = b;
    
    for(int i = 1; i <= m; i ++){
        char c;
        int k, res = 0;
        cin >> c >> k;
        vector<PII> del;
        if(c == 'U'){
            u += k;
            for(auto q = mp1.begin(); q != mp1.end(); q ++){
                auto [x, y] = *q;
                if(x.first < u){
                    if(mp[x]){
                        res ++;
                        mp[x] --;
                        del.push_back(x);
                    }
                }
                else break;
            }
            for(auto d : del) mp1.erase(d);
        }
        if(c == 'D'){
            d -= k;
            for(auto q = mp1.rbegin(); q != mp1.rend(); q ++){
                auto [x, y] = *q;
                if(x.first > d){
                    if(mp[x]){
                        res ++;
                        mp[x] --;
                        del.push_back(x);
                    }
                }
                else break;
            }
            for(auto d : del) mp1.erase(d);            
        }
        if(c == 'L'){
            l += k;
            for(auto q = mp2.begin(); q != mp2.end(); q ++){
                auto [x, y] = *q;
                PII x1 = {x.second, x.first};
                if(x.first < l){
                    if(mp[x1]){
                        res ++;
                        mp[x1] --;
                        del.push_back(x);
                    }
                }
                else break;
            }
            for(auto d : del) mp2.erase(d);            
        }
        if(c == 'R'){
            r -= k;
            for(auto q = mp2.rbegin(); q != mp2.rend(); q ++){
                auto [x, y] = *q;
                PII x1 = {x.second, x.first};
                if(x.first > r){
                    if(mp[x1]){
                        res ++;
                        mp[x1] --;
                        del.push_back(x);
                    }
                }
                else break;
            }
            for(auto d : del) mp2.erase(d);            
        }
        if(i & 1) ans1 += res;
        else ans2 += res;
    }
    cout << ans1 << ' ' << ans2 << '\n';
}

G. Money Buys Less Happiness Now

题意:给定n个物品,每次可以在第 i  月花费 ci 获得 1 幸福感,月底获得 x 元,求最多获得多少幸福感

思路:用优先队列维护即可,每次如果当前费用足够直接购买,否则查看先前购买的最贵的是不是比当前的还贵,如果是的就不要前面那个,选择当前的幸福感,否则就放弃当前的物品

void solve(){
    ll n, x, sum = 0;
    cin >> n >> x;
    priority_queue<ll> q;
    for(int i = 1; i <= n; i ++, sum += x){
        ll sal;
        cin >> sal;
        if(sum >= sal){
            q.push(sal);
            sum -= sal;
        }
        else if(q.size()){
            ll pre = q.top();
            q.pop();
            if(pre > sal){
                sum += pre;
                sum -= sal;
                q.push(sal);
            }
            else q.push(pre);
        }
    } 
    cout << q.size() << '\n';
}

 

标签:idx,946,auto,Codeforces,++,int,mp2,mp,Div
From: https://www.cnblogs.com/RosmontisL/p/18203636

相关文章

  • vue3+ts 指令拖拽div案例
    <template><divclass="box"v-move><divclass="header"></div><div>内容</div></div></template><scriptsetuplang="ts">import{ref,Directive,DirectiveBinding}......
  • Codeforces Round 945 (Div. 2) (A - E)
    A每一轮对总分的贡献都是\(2\),如果\(p_1+p_2+p_3\)为奇数则无解。\(p_1+p_2\lep_3\),最多\(p_1+p_2\)轮。\(p_1+p_2>p_3\),可以\(1,2\)轮流将\(3\)耗完,然后互相匹配,最多\(\dfrac{p_1+p_2+p_3}{2}\)。B如何判断一个\(k_0\)是否符合条件?处......
  • CF937Div4E 分段比较
    NearlyShortestRepeatingSubstring本题思路:(有长度L|n时,长度为L的串才是s的子串)降低枚举频率,此时枚举最小子串长度L(有L*x=s)。接下来考虑其,最多不匹配位置为1(当不匹配位置为2时直接弹出)题解认为:不同的字母也可能出现在前缀中(例如,......
  • Codeforces 401B Sereja and Contests 题解
    题目简述Sereja是一名程序员,他喜欢参加Codesorfes比赛。不过,乌兹兰的网络连接不太好,所以Sereja有时会跳过比赛。Codesorfes有两种类型的比赛,分为Div1和Div2。Div1和Div2这两轮可以同时进行(Div1轮不能在没有Div2的情况下进行)。每一轮都有一个唯一的标识符,各轮按......
  • Codeforces Round 944 (Div. 4)
    CodeforcesRound944(Div.4)需要一些trick的一场H:2-sat的板子,已经计入2-sat专题,此处不再详细描述。题目用矩阵包装和博弈包装,我们需要慢慢读题,分析样例,找到问题的关键点。G:题意:给定一个数组,数组中任何两个数异或<4的数对可以交换位置,可以交换无限次,求能够形成的字典序最......
  • Codeforces Round 945 (Div. 2) A-D
    A.ChessForThree模拟。首先可以发现每一次对局三人的得分总和加\(2\),所以若干次对局后得分总和也一定是\(2\)的倍数,然后为了使和棋数量尽可能多,一直让得分最高的两人和棋且得分数各减\(1\)直到无法做出和棋为止。#include<bits/stdc++.h>usingnamespacestd;#def......
  • Codeforces Round 945 (Div. 2)
    A-ChessForThree因为序列满足a<=b<=c的情况显然通过得分可以观察出得分总和必定为偶数否则不成立求的是最大平局数那么直接假设全部都是平局这时候发现如果c过大会导致后面的局数不是平局那么只用把c>a+b的情况取出而此时平均数为a+b点击查看代码#include<bits/stdc+......
  • Codeforces 769B News About Credit 题解
    题目简述波利卡普在由$n$名学生(包括他自己)组成的小组中学习,编号为$1$到$n$,波利卡普的编号始终是$1$。他们都在社交网络上注册,每个学生都有一个值$a_i$,表示第$i$名学生每天能发送的最大信息数。清晨,波利卡普知道了一个重要消息,他认为有必要通过私人消息紧急通知所有组员......
  • Codeforces 959B Mahmoud and Ehab and the message 题解
    题目简述小A想要给他的朋友小B发送了一条有$m$个单词的消息。他们的语言由编号从$a_1$到$a_n$的$n$个单词组成。一些单词具有相同的意思,因此存在$k$个单词组,其中每个组中的所有单词具有相同的意思。小A知道第$i$个单词可以以成本$m_i$发送。对于他的每个消息......
  • Codeforces 1113B Sasha and Magnetic Machines 题解
    题目简述有一个长度为$n$的正整数序列。你可以对这个数列进行最多$1$次的如下操作:选择两个数$i$和$j$,其中$1\leqi,j\leqn$并且$i\neqj$,并选择一个可以整除$a_i$的正整数$x$,然后将$a_i$变为$\frac{a_i}{x}$,将$a_j$变为$a_j\cdotx$。问你操作后,该序......