Codeforces Round #684 (Div. 2)

Codeforces Round #684 (Div. 2)

A.Buy the String

题意: 给定每个0的花费,给定每个1的花费,给定0和1互换的花费,问字符串变的花费

题解: 一共3的情况,不变、全0、全1,取个min即可

代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 2e5 + 10;
typedef long long LL;
typedef pair<int, int> PII;

int n, m, T, c0, c1, h;

int main() {
    cin >> T;
    while(T--) {
        cin >> n >> c0 >> c1 >> h;
        string s;
        cin >> s;
        int cnt0 = 0, cnt1 = 0;
        for (int i = 0; i < s.size(); ++i) {
            if (s[i] == '0') cnt0++;
            else cnt1++;
        }
        LL res = min(cnt0 * c0 + cnt1 * c1, min(n * c1 + cnt0 * h, n * c0 + cnt1 * h));
        cout << res << endl;
    }
    return 0;
}

B.Sum of Medians

题意: 给定一个数组,要求把数组划分为均等的k份,要求使得k份的中位数最大,打印最大的中位数和。

题解: 为了让中位数尽可能大,那么要让尽可能大的数字作为中位数。因此可以把数组排序,然后保证每个中位数后面都有足够的数字在他的后面,贪心之~

代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 2e5 + 10;
typedef long long LL;
typedef pair<int, int> PII;

int n, m, T, k, a[N];

int main() {
    cin >> T;
    while(T--) {
        cin >> n >> k;
        for (int i = 1; i<= n * k; ++i) scanf("%d", &a[i]);
        int pos = n * k - n / 2, step = n / 2 + 1;
        // cout << pos << " " << step << endl;
        LL sum = 0;
        for (int cnt = 0; cnt < k; ++cnt) {
            sum += a[pos];
            pos -= step;
        }
        cout << sum << endl;
    }
    return 0;
}

C1/C2.Binary Table

题意: 给定一个n * m的网格,每次操作可以选择一个2 * 2的网格里面的3个点,将其加一模2。问是否存在nm次操作,使得整个网格变成全0

题解: 看到nm就想到扫描整个网格一次,然后想起飞行员兄弟那题,如果扫描完一行就能够使得一行全为0,那么就不需要再去管这行了。对于最后2行要进行特判,对于最后的4个小方格,也需要特判。本题写了1个小时多,纯暴力,无语。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 105;
int t, n, m;
char b[N][N];
int a[N][N];
vector< pair<int, int> > op;
int main(){
    cin>>t;
    while(t--){
        cin >> n >> m;
        op.clear();
        int anss = 0;
        for (int i = 0; i < n;i++){
            for (int j = 0; j < m;j++){
                cin >> b[i][j];
                if(b[i][j]=='1'){
                    a[i][j] = 1;
                }
                else{
                    a[i][j] = -1;
                }
            }
        }
        for (int i = 0; i < n - 2;i++){
            for (int j = 0; j < m - 1;j++){
                if(a[i][j]==1){
                    op.push_back({i + 1, j + 1});
                    op.push_back({i + 1+1, j + 1});
                    op.push_back({i + 1, j + 1+1});
                    a[i][j] = -a[i][j];
                    a[i][j+1] = -a[i][j+1];
                    a[i+1][j] = -a[i+1][j];
                    anss++;
                }
            }
            if(a[i][m-1]==1){
                op.push_back({i + 1, m-1 + 1});
                op.push_back({i + 1+1, m-1 + 1});
                op.push_back({i + 1+1, m-1 -1+1});
                a[i][m-1] = -a[i][m-1];
                a[i+1][m-1] = -a[i+1][m-1];
                a[i+1][m-1-1] = -a[i+1][m-1-1];
                anss++;
            }
        }
        for (int j = 0; j < m - 2;j++){
            if(a[n-2][j]==1){
                op.push_back({n - 2 + 1, j + 1});
                op.push_back({n - 2 + 1+1, j + 1});
                op.push_back({n - 2 + 1, j + 1+1});
                anss++;
                a[n - 2][j] = -a[n - 2][j];
                a[n - 2+1][j] = -a[n - 2+1][j];
                a[n - 2][j+1] = -a[n - 2][j+1];
            }
            if(a[n-1][j]==1){
                op.push_back({n - 1 + 1, j + 1});
                op.push_back({n - 1 + 1, j + 1+1});
                op.push_back({n - 1 + 1-1, j + 1+1});
                anss++;
                a[n - 1][j] = -a[n - 1][j];
                a[n - 1][j+1] = -a[n - 1][j+1];
                a[n - 2][j+1] = -a[n - 2][j+1];
            }
        }
        if(a[n-2][m-2]==1&&a[n-1][m-2]==1&&a[n-2][m-1]==1&&a[n-1][m-1]==1){
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==1&&a[n-2][m-1]==1&&a[n-1][m-1]==1){
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==1&&a[n-1][m-2]==-1&&a[n-2][m-1]==1&&a[n-1][m-1]==1){
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==1&&a[n-1][m-2]==1&&a[n-2][m-1]==-1&&a[n-1][m-1]==1){
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==1&&a[n-1][m-2]==1&&a[n-2][m-1]==1&&a[n-1][m-1]==-1){
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==1&&a[n-1][m-2]==-1&&a[n-2][m-1]==-1&&a[n-1][m-1]==1){  //1 0
            op.push_back({n - 2 + 1, m - 2 + 1});                                    //0 1
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==1&&a[n-2][m-1]==1&&a[n-1][m-1]==-1){  //0 1
            op.push_back({n - 2 + 1, m - 2 +1});                                    //1 0
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }

        else if(a[n-2][m-2]==1&&a[n-1][m-2]==1&&a[n-2][m-1]==-1&&a[n-1][m-1]==-1){  //1 0
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //1 0
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==-1&&a[n-2][m-1]==1&&a[n-1][m-1]==1){  //0 1
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //0 1
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==1&&a[n-1][m-2]==-1&&a[n-2][m-1]==1&&a[n-1][m-1]==-1){  //1 1
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //0 0
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==1&&a[n-2][m-1]==-1&&a[n-1][m-1]==1){  //0 0
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //1 1
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==1&&a[n-1][m-2]==-1&&a[n-2][m-1]==-1&&a[n-1][m-1]==-1){  //1 0
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //0 0
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
             op.push_back({n - 2 + 1, m - 2 + 1});                                 
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==-1&&a[n-2][m-1]==1&&a[n-1][m-1]==-1){  //0 1
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //0 0
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //1 0
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==1&&a[n-2][m-1]==-1&&a[n-1][m-1]==-1){  //0 0
            op.push_back({n - 2 + 1+1, m - 2 + 1});                               //1 0
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
           op.push_back({n - 2 + 1, m - 2 + 1});                                 //0 1
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        else if(a[n-2][m-2]==-1&&a[n-1][m-2]==-1&&a[n-2][m-1]==-1&&a[n-1][m-1]==1){  //0 0
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //0 1
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1});                                 //1 0
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
            op.push_back({n - 2 + 1, m - 2 + 1+1});
            op.push_back({n - 2 + 1+1, m - 2 + 1});
            op.push_back({n - 2 + 1+1, m - 2 + 1+1});
            anss++;
        }
        cout << anss << endl;
        int cnt = 0;
        for (int i = 0; i < op.size();i++){
            cout << op[i].first << ' '<< op[i].second<<' ';
            cnt++;
            if(cnt==3){
                cout << endl;
                cnt = 0;
            }
        }
            
    }
    return 0;
}

D.Graph Subset Problem

题意: 给定一张n个点m条边的图,问是否能够找到一个点集,点集中每个点的度都大于等于k。问是否能够找到一个团,团中每个点的度都为k-1。如果能够找到点集或者团,那么输出其中一个即可,否则输出-1

题解: 找点集或者团可以使用类似拓扑排序的方法,每次把度数小于k的点放入队列,然后每次删除其连接点,度数减一,如果度数晓宇k,那么再次放入队列。在做这一过程的时候判断是否存在团,判断方法为暴力枚举,如果当前这个点的度为k-1,那么只需要将其所有的邻接点放入团内,然后枚举任意两个团内的点,二分判断a点是否为与b点的邻接点。

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
int const N = 2e5 + 10;
int n, m, T, k;
vector<int> e[N];
int din[N], st[N];

int main() {
    cin >> T;
    while(T--) {
        scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= n; ++i) {
            e[i].clear();
        }
        for (int i = 1; i <= m; ++i) {
            int a, b;
            scanf("%d%d", &a, &b);
            e[a].push_back(b), e[b].push_back(a);
        }
        queue<int> q;
        for (int i = 1; i <= n; ++i) {
            sort(e[i].begin(), e[i].end());
            din[i] = e[i].size();
            st[i] = 0;
            if (din[i] < k) {
                q.push(i);
                st[i] = 1;
            }
        }

        vector<int> clique;
        while(q.size()) {
            auto t = q.front();
            q.pop();

            st[t] = 2;
            if (din[t] == k - 1 && clique.empty() && (LL)k * (k - 1) / 2 <= m) {
                clique.push_back(t);
                for (auto ne: e[t]) {
                    if (st[ne] <= 1) clique.push_back(ne);
                }
                bool ok = true;
                for (auto u: clique) {
                    for (auto v: clique) {
                        if (u == v) continue;
                            if (!binary_search(e[u].begin(), e[u].end(), v)) ok = false;
                    }
                }
                if (!ok) clique.clear();
            }

            for (auto ne: e[t]) {
                if (--din[ne] < k && !st[ne]) {
                    q.push(ne);
                    st[ne] = 1;
                }  
            }
        }

        if (count(st + 1, st + n + 1, 0) > 0) {
            vector<int> res;
            for (int i = 1; i <= n; ++i) {
                if (!st[i]) res.push_back(i);
            }
            printf("1 %d\n", res.size());
            for (auto r: res) printf("%d ", r);
            puts("");
        }
        else if (!clique.empty()) {
            puts("2");
            for (auto c: clique) printf("%d ", c);
            puts("");
        }
        else puts("-1");
    }
    return 0;
}

E.Greedy Shopping

题意: 有n个数字,这n个数字单调不增,有m个操作:

操作1: 1 x y, 把前1 ~ x个数字都与y取max

操作2:2 x y, 询问从第x个数字开始往后,最多有几个数字的和小于等于y

题解: 可以使用线段树维护区间和,区间长度,区间最小值和最大值。

对于操作1,就是区间修改;对于操作2,如果当前的y小于区间最小值,那么直接return,如果当前y大于当前区间和,那么直接把区间和减掉y。

代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 2e5 + 10, NN = N * 4;
typedef long long LL;
typedef pair<int, int> PII;

int n, m, T;
LL sum[NN];
int len[NN], minv[NN], maxv[NN], lazy[NN], a[N];

void pushup(int u) {
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
    len[u] = len[u << 1] + len[u << 1 | 1];
    minv[u] = min(minv[u << 1], minv[u << 1 | 1]);
    maxv[u] = max(maxv[u << 1], maxv[u << 1 | 1]);
    return;
}

void build(int u, int l, int r) {
    if (l == r) {
        sum[u] = a[l], len[u] = 1, maxv[u] = minv[u] = a[l];
        return ;
    }
    int mid = (l + r) >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r) ;
    pushup(u);
}

void pushdown(int u, int l, int r) {
    int mid = (l + r) >> 1;
    if (!lazy[u]) return ;
    minv[u << 1] = minv[u << 1 | 1] = maxv[u << 1] = maxv[u << 1 | 1] = lazy[u];
    sum[u << 1] = (LL)len[u << 1] * lazy[u], sum[u << 1 | 1] = (LL)len[u << 1 | 1] * lazy[u];
    lazy[u << 1] = lazy[u << 1 | 1] = lazy[u], lazy[u] = 0;
    return;
}

void modify(int u, int l, int r, int L, int R, int y) {
    if (minv[u] >= y) return;
    if (l >= L && r <= R && maxv[u] < y) {
        sum[u] = (LL)y * len[u], minv[u] = maxv[u] = y, lazy[u] = y;
        return;
    }
    pushdown(u, l, r);
    int mid = (l + r) >> 1;
    if (L <= mid) modify(u << 1, l, mid, L, R, y);
    if (mid < R) modify(u << 1 | 1, mid + 1, r, L, R, y);
    pushup(u);
    return;
}

int query(int u, int l, int r, int L, int R, int &y) {
    if (minv[u] > y) return 0;
    if (l >= L && r <= R && sum[u] <= y) {
        y -= sum[u];
        return len[u];
    }
    pushdown(u, l, r);
    int mid = (l + r) >> 1;
    int res = 0;
    if (L <= mid) res += query(u << 1, l, mid, L, R, y);
    if (mid < R) res += query(u << 1 | 1, mid + 1, r, L, R, y);
    return res;
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); 
    build(1, 1, n);
    for (int i = 1; i <= m; ++i) {
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if (op == 1) modify(1, 1, n, 1, x, y);
        else printf("%d\n", query(1, 1, n, x, n, y));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值