Codeforces Round #603 (Div. 2) A、B

本篇为个人练习记录 题目传送门

说实话,这一场的A、B让我挺难忘,尤其是B题,一开始做的时候走了弯路,浪费了很多时间。B题数据的严紧也让我感到敬佩。

A. Sweet Problem

一道典型的思维题,对三种颜色的糖果数量进行排序,如果前两个数量之和小于第三个,则答案为前两个数量之和;否则,答案为糖果数量总和的一半。

AC代码

#include <bits/stdc++.h>
using namespace std;
int t, n, ans;
int a[4];
int main() {
    scanf("%d", &t);
    while(t --) {
        for(int i = 0; i < 3; i++) scanf("%d", &a[i]);
        sort(a, a + 3);
        if(a[0] + a[1] < a[2]) ans = a[0] + a[1];
        else ans = (a[0] + a[1] + a[2]) >> 1;
        cout << ans << '
';
    }
    
    return 0;
}

B. PIN Codes

这个是一个暴力模拟题,但也需要一点思维_

阅读题目后,会发现每一次测试的数量在(2le nle10),也就是说,只需要改变一个位置即可。这道题目的做法是利用map来储存出现过的数字,如果出现次数大于(1),那么就重新构造满足条件的数字。在保证输入顺序不变的条件下输出答案。

我刚开始的做法是利用set来记录出现过的数字,而且是边输入边查询,但是这样做有问题:当你输入一个数字,构造出合法数字并标记之后,如果后面的合法数字和构造出来的数字相同,后面输入的合法数字就变成非法了,导致答案出现错误。这种情况就得用set<pair<int, int> >了,但是和用map没什么实质性的区别。

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, t, x, b[N];
map<int, int> mp;

int solve(int v) {
    v -= v % 10;
    for(int i = 0; i <= 9; i++) if(!mp[v + i]) return v + i;
}

int main() {
    scanf("%d", &t);
    while(t --) {
        vector<int> ans;
        mp.clear(); 
        int cnt = 0;
        
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%d", &b[i]);
            mp[b[i]] ++;
        }
        
        for(int i = 0; i < n; i++) {
            if(mp[b[i]] > 1) {
                mp[b[i]] --; int k = solve(b[i]); cnt ++;
                mp[k] ++; ans.push_back(k);
            } else ans.push_back(b[i]);
        }
        
        printf("%d
", cnt);
        for(auto v : ans) printf("%04d
", v);
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/FrankOu/p/14461146.html