Codeforces Edu Round 65 A-E

A. Telephone Number

There is a winning strategy is the same as before with, \ (the n-- 10 \) exists before the number of bits \ (8 \) can be.

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 110;
int n;
char s[N];
int main(){
    int T; scanf("%d", &T);
    while(T--){
        scanf("%d%s", &n, s + 1);
        bool flag = false;
        for(int i = 1; i <= n - 10; i++)
            if(s[i] == '8') flag = true;
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}

B. Lost Numbers

Enumeration answer to violence.

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[6] = {4, 8, 15, 16, 23, 42};
int b[4];
bool inline judge(){
    for(int i = 0; i < 4; i++)
        if(a[i] * a[i + 1] != b[i]) return false;
    return true;
}
int main(){
    for(int i = 1; i <= 4; i++){
        printf("? %d %d\n", i, i + 1);
        fflush(stdout);
        scanf("%d", b + i - 1);
    }
    do{
        if(judge()){
            printf("! ");
            for(int i = 0; i < 6; i++)
                printf("%d ", a[i]);
            puts("");
            fflush(stdout);
            break;
        }
    }while(next_permutation(a, a + 6));
    return 0;
}

C. News Distribution

This ... is not a disjoint-set title bare it?

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 500010;
int n, m, f[N], size[N];
int inline find(int x){
    return f[x] == x ? x : f[x] = find(f[x]);
}
void inline merge(int x, int y){
    x = find(x), y = find(y);
    if(x == y) return ;
    if(size[x] > size[y]) swap(x, y);
    f[x] = y; size[y] += size[x];
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        f[i] = i, size[i] = 1;
    }
    for(int i = 1; i <= m; i++){
        int k, x; scanf("%d", &k);
        if(!k) continue;
        scanf("%d", &x); 
        for(int j = 1, y; j < k; j++){
            scanf("%d", &y);
            merge(x, y);    
        }
    }
    for(int i = 1; i <= n; i++)
        printf("%d ", size[find(i)]);
    return 0;
}

D. Bicolored RBS

Maintaining a variable \ (DEP \) , represents the current in the first layer, as long as the different parity set is met, the maximum number of layers of \ (\ lceil maxDep / 2 \ rceil \)

#include <cstdio>
#include <iostream>
#include <stack>
using namespace std;
const int N = 200010;
char str[N];
int n, ans[N], dep = 0;
int main(){
    scanf("%d%s", &n, str + 1);
    for(int i = 1; i <= n; i++){
        if(str[i] == '('){
            ans[i] = (++dep) & 1;
        }else if(str[i] == ')'){
            ans[i] = (dep--) & 1;
        }
    }
    for(int i = 1 ;i <= n; i++) 
        printf("%d", ans[i]);
    return 0;
}

E. Range Deleting

\ (Two - Pointer \) algorithm. We find two properties:

  1. If \ ((l, r) \ ) feasible, then \ ((l, r + 1 ), (l, r + 2) ... (l, x) \) are possible. Because something is deleted in ascending sequence in ascending order.

  2. If \ ((l, r) \ ) is not feasible, then \ ((l, r - 1 ), (l, r - 2) ... (l, l) \) is not feasible. Because obviously do not want to add something in the sequence have been feasible.

So, for every \ (L (1 <= L <= the X-) \) , we find a minimum of \ (r \) to satisfy the condition, the left point \ (l \) contribution to the answer is \ (n-- R & lt +. 1 \) . We call this the smallest \ (r \) to \ (r_ {min_l} \)

There is another nature, in the (L \) \ added after, \ (min_l R_ {} \) can only be increased or unchanged, can not be reduced. Because more than the number of exposed either qualified or still need to lose some of the numbers.

Thought of this, we can use a double pointer arithmetic. We need to use \ (O (1) \) of time to determine whether the addition of a number of feasible.

We can use the \ (O (n) \) time preprocessing four arrays:

  1. \ (S_i \) represents the number \ (i \) first appeared in the array position
  2. \ (T_i \) represents the number \ (I \) appears in the latest position of the array
  3. \ (Sx_i \) represents the number \ (i \) to \ (x \) first appeared in the array position
  4. \ (Tx_I \) represents the number \ (1 \) to \ (I \) appears in the latest position of the array
  • For left \ (l \) process, if we want to know so that \ (l - 1 \) to move to the \ (l \) is feasible:

If \ (the Tx [L - 2] <S [L -. 1] \) , is less than \ (l - 1 \) of all the number of positions in the first \ (l - 1 \) left can be moved.

  • For the right end of the process, it has been determined \ ([1, l - 1 ] \) and ([r + 1, x] \) \ number in the range satisfy the condition, it is judged \ ((L, R & lt) \) , whether the condition:

\ (Tx_ {l - 1} <Sx_ {r + 1} \) represents all or less \ (l - 1 \) numbers are greater than \ (r + 1 \) to the left of the number of the condition is satisfied, otherwise we We need to let \ (r \) increase.

Note that in the process of which we first find a minimum of \ (r \) so that \ ((1, r) \ ) to meet the conditions, and then expand \ (l \) among the 1 process, forced to increase \ (r \) , such as the nature \ (2 \) .

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 1000010, INF = 0x3f3f3f3f;
typedef long long LL;
int n, x, S[N], T[N], Sx[N], Tx[N];
int a[N];
LL ans = 0;
int main(){
    memset(S, 0x3f, sizeof S);
    scanf("%d%d", &n, &x);
    for(int i = 1; i <= n; i++){
        scanf("%d", a + i);
        if(S[a[i]] == INF) S[a[i]] = i;
        T[a[i]] = i;
    }
    for(int i = 1; i <= x; i++)
        Tx[i] = max(Tx[i - 1], T[i]);
    
    Sx[x + 1] = INF;
    for(int i = x; i; i--)
        Sx[i] = min(Sx[i + 1], S[i]);
    
    int r = x - 1;
    while(r && T[r] < Sx[r + 1]) r--;
    for(int l = 1; l <= x; l++){
        if(l > 2 && S[l - 1] < Tx[l - 2]) break;
        while(r <= x && (r < l || Tx[l - 1] > Sx[r + 1])) 
            r++;
        ans += x - r + 1;
    }
    printf("%lld\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/dmoransky/p/11311781.html