Codeforces Round #605 (Div. 3)

https://codeforces.com/contest/1272/

A - Three Friends

Question is intended: to three points, each point is moved up to a cell, and for the minimum distance between the three points twenty-two.

Solution: After the middle of the sort frequently point does not matter, about the point near the middle of the line can be reduced up to two degrees, the shortest reduced to zero. The answer is obviously twice the length of a line.

void test_case() {
    int a[4];
    scanf("%d%d%d", &a[1], &a[2], &a[3]);
    sort(a + 1, a + 1 + 3);
    int maxd = a[3] - a[1];
    if(maxd <= 2)
        maxd = 0;
    else {
        maxd -= 2;
        maxd *= 2;
    }
    printf("%d\n", maxd);
}

B - Snow Walking Robot

Meaning of the questions: to a chart, from the origin to go up and down, walking track in addition origin can not have any intersection, and the origin only twice. To a sequence, you can rearrange them moves, if not first delete and then rearranged as little as possible.

Solution: If there is at least up and down each one, then take a rectangle. Otherwise, if only up and down or left and right and only then go one step back.

Note that the string 1 start from the beginning, also adjusted for a long time, really play.

char s[100005];
void test_case() {
    scanf("%s", s + 1);
    int cntu = 0, cntl = 0, cntd = 0, cntr = 0;
    int n = strlen(s + 1);
    for(int i = 1; i <= n; ++i) {
        if(s[i] == 'U')
            ++cntu;
        else if(s[i] == 'D')
            ++cntd;
        else if(s[i] == 'L')
            ++cntl;
        else
            ++cntr;
    }
    cntl = min(cntl, cntr);
    cntr = cntl;
    cntu = min(cntu, cntd);
    cntd = cntu;
    if(cntr == 0) {
        if(cntd) {
            puts("2");
            puts("UD");
            return;
        } else {
            puts("0");
            puts("");
            return;
        }
    } else if(cntd == 0) {
        puts("2");
        puts("LR");
        return;
    }
 
    int n2 = cntl + cntr + cntu + cntd;
    printf("%d\n", n2);
    while(cntu--)
        putchar('U');
    while(cntr--)
        putchar('R');
    while(cntd--)
        putchar('D');
    while(cntl--)
        putchar('L');
    putchar('\n');
    return;
}

C - Yet Another Broken Keyboard

Meaning of the questions: to a string, and a bunch of characters, find the number of sub-strings consisting only of these characters.

Solution: just look at the combination.

char s[200005];
bool vis[128];
void test_case() {
    int n, k;
    scanf("%d%d%s", &n, &k, s + 1);
    for(int i = 1; i <= k; ++i) {
        char c[2];
        scanf("%s", c);
        vis[c[0]] = 1;
    }
    ll ans = 0, tmp = 0;
    for(int i = 1; i <= n; ++i) {
        if(vis[s[i]]) 
            ++tmp;
        else {
            ans += tmp * (tmp + 1) / 2;
            tmp = 0;
        }
    }
    ans += tmp * (tmp + 1) / 2;
    tmp = 0;
    printf("%lld\n", ans);
}

D - Remove One Element

The meaning of problems: deleting an element from at most a sequence, seeking to generate new sequence in the longest sub-string length strictly increased.

Solution: a more disgusting problem, began to consider a dp, but in fact there is a simpler approach: a strictly increasing each segment divided into segments, then there may connect only when the beginning of the end of the segment or segments are deleted before and after the two different segments. Note that if the case is only one element of a segment of time.

int a[200005], fi[200005], se[200005];
void test_case() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    int top = 1;
    fi[1] = 1, se[1] = 1;
    for(int i = 1; i <= n; ++i) {
        if(a[i] > a[i - 1])
            se[top] = i;
        else {
            fi[++top] = i;
            se[top] = i;
        }
    }
    int ans = se[1] - fi[1] + 1;
    for(int i = 2; i <= top; ++i) {
        ans = max(ans, se[i] - fi[i] + 1);
        if(se[i] == fi[i] && i + 1 <= top) {
            if(a[fi[i + 1]] > a[se[i - 1]])
                ans = max(ans, se[i - 1] - fi[i - 1] + 1 + se[i + 1] - fi[i + 1] + 1);
        } else {
            if(a[se[i - 1] - 1] < a[fi[i]])
                ans = max(ans, se[i - 1] - fi[i - 1] + 1 + se[i] - fi[i] + 1 - 1);
            else if(a[se[i - 1]] < a[fi[i] + 1])
                ans = max(ans, se[i - 1] - fi[i - 1] + 1 + se[i] - fi[i] + 1 - 1);
        }
    }
    printf("%d\n", ans);
}

Dp If it is, then, to consider that there is no front element is deleted too. But also affected by the end of the state. Provided dp [0] [i] i is represented by the end of the longest consecutive rises without deleting the length of the substring, dp [1] [i] for the i is deleted, dp [2] [i] is already use the opportunity to delete, delete and not of i.

int a[200005], dp[3][200005];
void test_case() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    int ans = 0;
    for(int i = 1; i <= n; ++i) {
        dp[0][i] = a[i] > a[i - 1] ? dp[0][i - 1] + 1 : 1;
        dp[1][i] = dp[0][i - 1];
        dp[2][i] = max(a[i] > a[i - 1] ? dp[2][i - 1] + 1 : 1, i >= 2 ? (a[i] > a[i - 2] ? dp[1][i - 1] + 1 : 1) : 1);
        ans = max(ans, dp[0][i]);
        ans = max(ans, dp[2][i]);
    }
    printf("%d\n", ans);
}

Guess you like

Origin www.cnblogs.com/KisekiPurin2019/p/12036076.html