Codeforces Round #571 (Div. 2)

A. Vus the Cossack and a Contest

sign.

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

int main() {
    int n, m, k;
    while (scanf("%d%d%d", &n, &m, &k) != EOF) {
        if (min(m, k) >= n) {
            puts("YES");
        } else {
            puts("NO");
        }
    }
    return 0;
}

C. Vus the Cossack and Strings

The meaning of problems:
given \ (a, b \) two strings 01, \ (| A | \ GEQ | B | \) , asks \ (A \) in all the length is equal to \ (| B | \) substrings and \ (B \) after an exclusive-oR \ (1 \) number for the even-numbered sub-string how many.

Ideas:
The most natural idea is to enumerate \ (a \) in all of length \ (| b | \) substring.
In fact, in the end we do not care \ (1 \) the number of how many, only need to be concerned about parity.
After we come up with the first substring violence XOR (1 \) \ number modulo value 2.
Consider again, the pointer moves to the right one, what would happen?
For example,
011000
00110

01100--> 11000
What happens?

We note that this process is equivalent to \ (b \) string to the right move one,
then for \ (a \) string, the first character is removed and increase the last character in the middle of the same character.
Then for the middle of the character, its corresponding \ (b \) values corresponding prior former (b \) \ value, then you want to inherit its status.
So if you and the former are the same, then a corresponding prior before \ (b \) values shift over time does not change the parity of the answer.
Doing this changes.
Prefix exclusive or click.

Code:

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

#define N 1000010
char s[N], t[N];

int main() {
    while (scanf("%s%s", s + 1, t + 1) != EOF) {
        int lens = strlen(s + 1), lent = strlen(t + 1);
        int res = 0, Xor = 0, tot = 0;   
        for (int i = 1; i <= lent; ++i) { 
            if (s[i] != t[i]) {
                tot ^= 1;  
            }
            if (i > 1 && s[i] != s[i - 1]) Xor ^= 1; 
        }
        res += tot ^ 1;
        for (int i = lent + 1; i <= lens; ++i) {
            if (s[i] != s[i - 1]) Xor ^= 1; 
            int pre = i - lent;
            if (pre > 1 && s[pre] != s[pre - 1]) Xor ^= 1;
            tot ^= Xor;
            res += tot ^ 1; 
        }
        printf("%d\n", res);
    }
    return 0;
}

D. Vus the Cossack and Numbers

The meaning of problems:
given \ (n-\) real numbers, and to their \ (0 \) , now require rounding down the whole or each real numbers such that their sum is still \ (0 \) .

Ideas:
first of all have to go the whole number, then see how much difference, just make it up.

When dealing with real strings, and forget to consider the issue FST 0 -0 up.

Code:

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

#define ll long long
#define N 100010
int n;
char s[110];
int a[N], b[N], c[N];

int main() {
    while (scanf("%d", &n) != EOF) {
        int can = 0;
        ll sum = 0;
        for (int i = 1; i <= n; ++i) {
            scanf("%s", s + 1);
            a[i] = 0, b[i] = 0;
            int j = 1, len = strlen(s + 1);
            int f = 1;
            if (s[1] == '-') ++j, f = -1;   
            for (; j <= len && s[j] != '.'; ++j) {
                a[i] = a[i] * 10 + s[j] - '0';
            }
            for (++j; j <= len; ++j) {
                b[i] = b[i] * 10 + s[j] - '0';
            }
            a[i] *= f;
            if (b[i] != 0) {
                ++can;
                if (f == -1) {
                    --a[i];
                }
            }
            sum += a[i];
        }
        sum = abs(sum);
        //assert(sum <= can);   
        for (int i = 1; i <= n; ++i) {
            if (sum > 0 && b[i] != 0) {
                ++a[i];
                --sum;
            }
        }
        for (int i = 1; i <= n; ++i) {
            printf("%d\n", a[i]);
        }   
    }
    return 0;
}

F. Vus the Cossack and a Graph

The meaning of problems:
there is a \ (n-\) points, \ (m \) edges FIG. Request a maximum retention \ (\ left \ lceil \ frac {n + m} {2} \ right \ rceil \) edges, such that the new degree of each point \ (f_i \ geq \ left \ lceil \ frac {d_i} 2} {\ right \ rceil \) , where \ (D_i \) is the degree of the original.

Ideas:
Obviously, as will be appreciated by deleting \ (m - \ left \ lceil \ frac {n + m} {2} \ right \ rceil \) edges, to leave as much as no harm edge,
then we can consider most deleting each point in degrees \ (D_i D_i = - \ left \ lceil \ FRAC D_i} {2} {\ right \ rceil \) , then we prefer omitted \ (D_i \) small dots adjacent \ (D_i \) side of the big points.
Because of this greed can ensure \ (D_i \) small dots adjoining edges can be preferentially removed, otherwise \ (D_i \) small point adjacent to the point corresponding to sides could because they were discarding the other side, resulting in available degree is not enough these edges can not be deleted.
As for the available large degree point, deleting little effect on what side.
And we found a \ (D_i \) minimum point, then to how to choose its adjacent sides to delete it?
To select adjacent edges of corresponding points \ (D_i \) a large deletion.
Because if you choose \ (D_i \) small, it may be finished delete their \ (D_i \) are changed to 0 and can not be deleted.
But there may be two points are adjacent to a \ (D_i \) big points, so you can delete the two sides, or only delete an edge.

Code:

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

#define N 1000010
#define pii pair <int, int>
#define fi first
#define se second
int n, m;
int del[N];  
vector < vector <pii> > G; 
int d[N], a[N];
int e[N][2];  

int main() {
    while (scanf("%d%d", &n, &m) != EOF) {
        memset(del, 0, sizeof del); 
        memset(d, 0, sizeof d);
        G.clear();
        G.resize(n + 1);
        int needdel = m - (n + m + 1) / 2; 
        for (int i = 1, u, v; i <= m; ++i) {
            scanf("%d%d", &e[i][0],  &e[i][1]);
            u = e[i][0], v = e[i][1];
            G[u].push_back(pii(v, i));
            G[v].push_back(pii(u, i));
            ++d[u]; ++d[v]; 
        }
        if (needdel <= 0) {
            printf("%d\n", m);
            for (int i = 1; i <= m; ++i) {
                printf("%d %d\n", e[i][0], e[i][1]);  
            }
            continue;
        }
        priority_queue <pii, vector <pii>, greater <pii> > pq; 
        for (int i = 1; i <= n; ++i) {
            d[i] = d[i] - (d[i] + 1) / 2;
            pq.push(pii(d[i], i));
        }
        int u, v;
        while (needdel > 0) {
            u = 0;
            while (!pq.empty()) {
                u = pq.top().se; pq.pop();
                if (d[u] <= 0) {
                    u = 0;
                    continue; 
                }
                else break;
            }
            if (u == 0) break;  
            sort(G[u].begin(), G[u].end(), [](pii x, pii y) {
                return d[x.fi] > d[y.fi];       
            }); 
            for (auto it : G[u]) {
                if (del[it.se]) continue;
                v = it.fi;
                if (d[v] <= 0) continue; 
                del[it.se] = 1;
                --d[u]; --needdel;
                --d[v];
                if (d[v] > 0) {
                    pq.push(pii(d[v], v));
                }
                if (d[u] <= 0 || needdel <= 0) break;  
            }
        }
        int sze = (n + m + 1) / 2;
        printf("%d\n", sze);
        int cnt = 0;
        for (int i = 1; i <= m; ++i) {
            if (del[i] == 0) {
                ++cnt;
                printf("%d %d\n", e[i][0], e[i][1]);
            }
        }
        assert(sze == cnt); 
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Dup4/p/11105590.html