CF Round #498 (Div. 3) 前三题题解(A+B+C)

刚从Java转学C++,各种不熟,时间限度内只做了三题,犯了很多初学者会犯的错误,疯狂查stl的用法。记录一下前三题,都不难。

A. Adjacent Replacements
真实签到题,如果按照题目说法去模拟铁tle,其实题都不用看,观察样例可知奇数不变,偶数减一输出即可。
ac代码:

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

int main() {
    int n, in[1005];
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        scanf("%d", &in[i]);
    }

    for(int i = 0; i < n; i++) {
        if(in[i] % 2 == 0){
            in[i]--;
        }
        printf("%d", in[i]);
        if(i < n - 1) {
            printf(" ");
        }
    }
    printf("\n");
    return 0;
}

B. Polycarp’s Practice
题目很长很恶心,有点难看懂。题意是让你把一个数组分成k段,这k段的最大值相加要最大,special judege,答案不唯一。
其实就是求top k,然后扫一遍,见top k就分段。
第一步先求top k,然后用map存储。
一直记得数据结构老师说过求top k用堆的效率很优秀,所以这里选用优先队列。
ac代码:

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

int main() {
    int n, k, in[2005];
    scanf("%d%d", &n, &k);
    priority_queue<int, vector<int>, less<int> > wait;
    map<int, int> m;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &in[i]);
        wait.push(in[i]);
    }

    int sum = 0;
    for(int i = 0; i < k; i++) {
        int get = wait.top();
        wait.pop();
        m[get]++;
        sum += get;
    }

    int pre = 0, cnt = 0;
    printf("%d\n", sum);
    for(int i = 1; i <= n ; i++) {
        if(m[in[i]] > 0) {
            if(cnt == k - 1) {
                printf("%d\n", n - pre);
                break;
            }
            printf("%d ", i - pre);
            pre = i;
            m[in[i]]--;
            cnt++;
        }
    }
    return 0;
}

C.cf炸了看不到题目.jpg
这题,不像是acm会出现的题,更像是学语言时课本后面会出的作业题。简化题目后(其实题目最后已经用几句话帮你简化好了)就是求数组一头一尾两部分能划分出的数值最大、保证相等的和是多少。头部是sum1,尾部是sum3。
拿一个头指针一个尾指针,小的那一方sum就前进指针,相等时更新答案,并且让两个指针同时前进即可。
有一点要注意的是要严防指针越界,并且sum要用long long,输出要用lld(难受,因为这个wa了两发,用Java从来不考虑输出问题)。
ac代码:

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

int main() {
    int n, in[200005];
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &in[i]);
    }
    ll sum1 = 0, sum3 = 0, ans;
    int i = 0, j = n + 1;
    while(i < j) {
        if(sum1 == sum3) {
            ans = sum1;
            sum1 += in[++i];
            sum3 += in[--j];
        }
        while(sum1 < sum3 && i < n) {
            sum1 += in[++i];
        }
        while(sum3 < sum1 && j > 1) {
            sum3 += in[--j];
        }
    }
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/cymbals/article/details/81084408
今日推荐