Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) C. Messy

[Link title] C title link

[Title] greedy type, simulation

[Title] has the effect t test sample. You are given a string of length n, by asking you

In one operation you can choose any consecutive substring of s and reverse it. In other words, you can choose any substring s[l…r]=sl,sl+1,…,sr and change the order of elements in it into sr,sr−1,…,sl.

Reverse operation so that the outermost bracket matching has k. Finally, the output of your total operation and the operation of those positions.

[Problem-solving ideas]
(1) look at the input (just take a look at the sample)
the INPUT
10 3
)) () () () ((
I want to reach the outermost layer three, then four characters directly to the front change has become () () then add back a this (...), can not it do? (this is where the idea of this title greedy)
(2) Note that the output of such a sentence topic,

In the first line print integer m (0≤m≤n) — the number of operations. You do not need to minimize m, any value is suitable.

Meaning that your total operation may be a number from 0 to n of them, but the title does not require that you have each operand is minimal, so you can count every time operations are the largest, that is n, then the solution the total number of questions need to consider the minimum operating time can make the subject easier.

[Problem-solving ideas I wrong] I noticed earlier in order to be () () () () () () () ... like this, then the front of each even-numbered position (position according to an array subscript) on is '(' and position are odd ')', which also makes me want to determine whether the conditions for each position, if it does not go looking for (even position if it does not, then I went to Looking back this is the position of the first '(' place, if an odd location does not meet, I went back to find the position of the first one is ')' place, then reverse operation)

Where is this wrong point in it? Although not able to implement the code, but I probably know the wrong place is so few

  1. Time complexity will be surprisingly high, because you need to find a lot of times, the outer layer be k-1 operations, the inner str.size () does not find a place in line, and find a place to look for non-compliance can be matched descending place (k-1) * (len) (m), and finally the last one needed to brace processes (to look for the same reason)
  2. Finally braces will deal with the problem, suppose I want to k = 5, I need five rooms, two places that you just deal with this bold, and
    () () () () ) ) () ( )
    If, after a bold position and location of the first forms a bold position to match it? That last braces become established yet?

[Right] solving ideas put directly in front of the k-1 () stored first, followed by the word [n - (k-1) * 2] / 2 th left bracket, and [n - (k-1 ) * 2] / 2 right parenthesis, almost like a ((((...)))) , and finally take your bracket character of this character input and stored to be compared like

Note written reverse function, 1) What is the length of your reverse!

/**
 *    This code has been written by YueGuang, feel free to ask me question. Blog: http://www.yx.telstudy.xyz
 *    created:
 */
#include <cstdio>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i, a, b) for(int i = a; i < b; i++)
#define rep_(i, a, b) for(int i = a; i <= b; i++)
#define rep1(i, n) for(int i = 1; i < n; i++)
#define rep1_(i, n) for(int i = 1; i <= n; i++)
#define pb(x) push_back(x);
#define si(x) scanf("%d", &x);
#define sl(n) scanf("%lld", &n);
#define pi(a) printf("%d\n", a);
#define RepAll(a) for(auto x: a)
#define cout(ans) cout << ans << endl;
typedef long long ll;

using namespace std;
const int maxn = 2048;
/* You do not need to minimize m, any value is suitable.*/
string str;
void rev(int i, int j){
    /* i位置到j位置的字符进行转换*/
    for(int start = 0; start < (j - i + 1)/2; start++){
        swap(str[start + i], str[j - start]);
    }
}

int main(){
    int t; scanf("%d", &t);
    while(t--){
        int k, n;scanf("%d%d",&n, &k);k--;
         cin >> str;
        pi(n);
        string ans;
        rep(i, 0, k){ ans += "()";}
        rep(i, 0, (n - 2 * k) / 2){ans += "(";}
        rep(i, 0, (n - 2 * k) / 2){ans += ")";}
        rep(i, 0, n){
            int p = i;
            while(str[p] != ans[i]){p++;}//查找和i相同的地方
            rev(i, p);
            cout << i+1 << " " << p+1 << '\n';
        }
        }
        return 0;
}

Published 20 original articles · won praise 3 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_43382350/article/details/103243530