Luogu P5587 practice typing problem solution

Luogu P5587 practice typing problem solution

EDITORIAL

As we all know, this is a solution to a problem, but a solution to a problem is the problem of yellow ......

It comes from the Luo Gu month season ...... but do not when the subject is not the same as it \ (QAQ \) ?

Portal Click here: typing game , I wrote this solution to a problem, hope to help more people

Part of the solution to a problem

Intuitive idea

Obviously the idea is that you run into the back of a character with a '<' character, do not this, you can open an additional string able to save the last copy

But think carefully about it, this is not feasible, because there may be multiple '<' together.

If you follow the above simulation that way, individuals do not think there is any good way. So we may need to optimize it.

Improvement ideas

He called the outset that in accordance with the above idea \ (50 \) points to think is not correct.

Then I think of the list according to the way, for some deleted '<', we just need to delete the character to jump off the top of the first place has not been deleted characters can be. So I just took a \ (pre \) array record this deletion extends up to where a character, there is a \ (Next \) array as a pointer to the top of the deleted skip to a not deleted of all processed and then simulated character can take.

Implementation details

Obviously the above is feasible. Think about how to achieve specific, how to update \ (pre \) and \ (Next \) two arrays.

Below we agreed string of each line from the first start, in order to operate.

Scanning each line \ (i \) , we met for the first of a deletion (location \ (J \) ), there may be several situations:

  1. Is the first character, then \ (pre [J] = 1 \) , \ (the Next [J] = J + 1 \) (in fact, \ (J = 1 \) ) situation;

  2. It is not the first character, but \ (pre [j-1] \) is not zero. This shows that the previous deletion is continuous, so we have to delete a character.

So how does it work? Actually very simple, as long as you: \ (pre [J] = pre [J-1] -1 \) , \ (the Next [pre [J]] = J + 1 \) can be.

Here people would have questions, why always let \ (the Next [] = J + 1 \) ?

So we continue to consider, if j + 1 is still deleted, \ (Next \) will certainly jump and then the next one, otherwise \ (j + 1 \) is the answer.

However, to be noted that Japanese sentence \ (pre [j-1] -1 = 0 \) case, this time should be assigned directly \ (1 \) .

  1. It is not the first character, and \ (pre [J-1] = 0 \) , then directly \ (pre [j] = j -1, Next [pre [j]] = j + 1 \) can be.
  • Then we finished with this topic. If you still do not understand, please understand it binding under the code:

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
string a[N], b[N], x, y;
int Next[N], pre[N];
int main() {
    int n = 0, m = 0; 
    for(int i = 1; ; i++) {
        getline(cin, x);
        if(x == "EOF") break;
        a[++n] = x;
    }
    
    for(int i = 1; ; i++) {
        getline(cin, x);
        if(x == "EOF") break;
        b[++m] = x;
    }
    
    for(int i = 1; i <= n; i++) {
        memset(Next, 0, sizeof Next);
        memset(pre, 0, sizeof pre);
        int size = a[i].size();
        y = a[i], x = " " + a[i], a[i] = x, x = ""; 
        bool flag = 0;
        for(int j = 1; j <= size; j++) 
            if(a[i][j] == '<') {
                if(j == 1) pre[j] = 1;
                else if(pre[j - 1]) {
                    if(pre[j - 1] > 1)
                        pre[j] = pre[j - 1] - 1;
                    else pre[j] = 1;
                } else if(!pre[j - 1])
                    pre[j] = j - 1;
                Next[pre[j]] = j + 1;
                flag = 1;
            }
            
        if(flag == 0) {
            a[i] = y;
            continue;
        }
        for(int j = 1; j <= size; j++) {
            if(!Next[j]) x += a[i][j];
            else j = Next[j] - 1;
        }
        a[i] = x;
    }
    
    for(int i = 1; i <= n; i++) {
        memset(Next, 0, sizeof Next);
        memset(pre, 0, sizeof pre);
        int size = b[i].size();
        y = b[i], x = " " + b[i], b[i] = x, x = ""; 
        bool flag = 0;
        for(int j = 1; j <= size; j++) 
            if(b[i][j] == '<') {
                if(j == 1) pre[j] = 1;
                else if(pre[j - 1]) {
                    if(pre[j - 1] > 1)
                        pre[j] = pre[j - 1] - 1;
                    else pre[j] = 1;
                } else if(!pre[j - 1])
                    pre[j] = j - 1;
                Next[pre[j]] = j + 1;
                flag = 1;
            }
            
        if(flag == 0) {
            b[i] = y;
            continue;
        }
        for(int j = 1; j <= size; j++) {
            if(!Next[j]) x += b[i][j];
            else j = Next[j] - 1;
        }
        b[i] = x;
    }
    
    int ans = 0;
    for(int i = min(n, m); i; i--) { 
        // 这里采用倒序是为了避免重复计算 min(n,m) 
        int len = min(a[i].size(), b[i].size());
        if(len == 0) continue;
        for(int j = 0; j < len; j++) 
            if(a[i][j] == b[i][j]) ans++;
        
    }
    int T; scanf("%d", &T);
    ans = (int)((double)ans * 60.0 / (double) T + 0.5);
    printf("%d", ans);
    return 0;
}

Of course, there will be more good writing, but I think personal understanding is more important.

Written on the back

Month when the tournament only got \ (50pts \) , the reason actually said Pham Van month contest problems surface there are no '<'?

What else can I say? ......

Guess you like

Origin www.cnblogs.com/Ning-H/p/11666629.html