Codeforces 라운드 # 602 (사업부. 2 Technocup 2,020 토너먼트 3 기준) C. 질러 构造

C. 지저분한

당신이 그것을 청소하기로 결정, 그래서 당신은 당신의 지저분한 방을 품고있다.

객실은 브라켓 시퀀스 S = s1s2 ... SN 길이 n입니다. 이 문자열의 각 문자는 개구 괄호 '('또는 닫기 괄호 ')'중입니다.

하나의 작업에서 당신의 모든 연속적인 문자열을 선택하고 취소 할 수 있습니다. 즉, 임의의 문자열 S [1 ... R = SL, SL + 1, ..., SR을 선택하고 SR SR-1, ..., SL로 요소의 순서를 변경.

예를 들어, S [2 ... (4)] S = 문자열의 「((())) "은 S와 동일 할 것이다 서브 스트링 역방향 결정한다면 ="() (()) ".

정규 (일명 균형) 브래킷 시퀀스 문자 '1'과 '+'시퀀스의 원래의 문자 사이를 삽입하여 정확한 연산 식으로 변환 될 수있는 브래킷 서열이다. 그리고 예를 들어, 브래킷 서열 "()", "(())"정규 ( '(1) + (1) ","(+ 1 (1) +1) "를 생성 식이다)되고 "()"와 "("없습니다.

"(", "((", "(()", "스트링의 접두사는 위치 1에서 시작 예를 들어, S 대 ="(()) () "6 프리픽스가있는 문자열이며 (()) ","(() () "및"(()) () ".

당신의 의견에, 단정하고 깨끗한 객실들 브라켓 순서 즉 :

전체 문자열 s는 일반 브라켓 순서입니다;
및 (전체들 자체를 포함하여)이 규칙적 시퀀스 정확히 K 프리픽스있다.
예를 들면, K = 2, 다음 "(()) ()"깔끔하고 청정실 경우.

당신은 당신의 방은 단정하고 깨끗하게 만들기 위해 대부분의 n 개의 작업에 사용하려고합니다. 동작들은 순차적으로 잇달아인가된다.

답이 존재 함을 보장한다. N 이하의 작업에서 원하는 구성을 달성하기 위해 어떤 방법을 찾을 : 당신은 작업의 수를 최소화 할 필요가 없습니다.

입력

입력에서 테스트 케이스의 수 - 제 라인 번호 t (1≤t≤100) 정수를 포함한다. 그런 다음 t 테스트 케이스은 다음과 같습니다.

테스트 케이스의 첫 번째 라인은 두 정수 N과 K 포함 (1≤k≤n2,2≤n≤2000를 짝수 N) - (S)의 길이가 일정한 프리픽스 필요한 개수.

주어진 브래킷 시퀀스 - 테스트 케이스의 두 번째 행은 길이 n (S)를 포함한다. 그것은 '('와 ')'에만 포함되어 있습니다.

주어진 문자열 정확히 N2 문자 '('정확히 N2 문자 ')'이 있다는 것을 보장한다.

모든 값의 총합 N을 통해 모든 입력에서 테스트 케이스가 2,000을 초과하지 않는다.

산출

각 테스트 케이스에 대한 답을 인쇄 할 수 있습니다.

첫번째 라인 인쇄 정수 m (0≤m≤n)에서 - 연산의 수. 당신은 어떤 값이 적당하다, m을 최소화 할 필요가 없습니다.

다음의 m 라인 동작의 설명을 프린트 각 라인 S [1 ... R = slsl + 1 ... SR 단일 역 동작을 나타내는 두 개의 정수 L, R (1≤l≤r≤n)를 포함한다. 동작들은 순차적으로 잇달아인가된다.

모든 작업 후 최종 S는 또한 규칙적 (들 포함)을 정확하게 K 프리픽스되어야 정규이어야한다.

답이 존재 함을 보장한다. 몇 가지 답변이 있다면 당신은 어떤을 인쇄 할 수 있습니다.

입력
4
8 2
(() () ())
× 103
)) () () () ((
2 1
()
2 1
) (
출력
4
3 4
1
5 8
2
3
4 10
1 4
6 7
0
1
1 2

노트

첫번째 예에서, 최종 시퀀스는 "() (())", 두 프리픽스 일정한 곳에, "()"및 "() (())". 참고 예제 출력에서 ​​"5 8"을 제외한 모든 작업이 쓸모 있음 (그들이없는 변화의 수행).

문제의 의미

당신은 시퀀스 길이 n은 브래킷을주는 바로 그 k는 정확히 정당한 접두사 브래킷을 얻을 수 있도록 / 2 (즉,이 N / 2), 당신은 대부분의 N 반전 작동에 필요 없음.

문제 해결

이 n 번을 전환 할 수 있기 때문에 첫째, 그래서 어떤 순서로 얻을 수 있습니다.

그럼 난 그냥 라인에 건설했다.

당신이 정당한 접두사를 k로한다고 가정 내가 브래킷을 접두사를 통해 K-1 일 이전에 () () () () () () 생성자, 나머지 브래킷의 마지막 ((((.....)) )) 상에 구축되므로

코드

#include<bits/stdc++.h>
using namespace std;
int n,k;
string s;
void solve_swap(int x,int y){
    while(x<y){
        swap(s[x],s[y]);
        x++,y--;
    }
}
string get_str(int n,int k){
    string tmp="";
    for(int i=0;i<k-1;i++){
        tmp+="(";
        tmp+=")";
    }
    int len = n-tmp.size();
    for(int i=0;i<len/2;i++){
        tmp+="(";
    }
    for(int i=0;i<len/2;i++){
        tmp+=")";
    }
    return tmp;
}
void solve(){
    cin>>n>>k;
    cin>>s;
    vector<pair<int,int>>ans;
    string final_str = get_str(n,k);
    for(int i=0;i<s.size();i++){
        if(s[i]!=final_str[i]){
            for(int j=i+1;j<s.size();j++){
                if(s[j]==final_str[i]){
                    solve_swap(i,j);
                    ans.push_back(make_pair(i+1,j+1));
                    break;
                }
            }
        }
    }
    //cout<<s<<endl;
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        cout<<ans[i].first<<" "<<ans[i].second<<endl;
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--)solve();
}

추천

출처www.cnblogs.com/qscqesze/p/11925073.html