你厌倦了你那乱糟糟的房间,所以你决定把它打扫干净。
你的房间是一个长度为n的括号序列s=s1s2...sn。这个字符串的每个字符都是一个开括号'('或一个闭括号')'。
在一次操作中,你可以选择s的任何一个连续的子串并将其倒置。换句话说,你可以选择任何子串s[l...r]=sl,sl+1,...,sr并将其中的元素顺序改为sr,sr-1,...,sl。
例如,如果你决定将字符串s="(()) "的子串s[2...4]反转,它就等于s="()()"。
正则(又称平衡)括号序列是指通过在序列的原始字符之间插入字符'1'和'+',可以转化为正确的算术表达式的括号序列。例如,括号序列"()()"、"()) "是有规律的(产生的表达式是。"(1)+(1)", "((1+1)+1)"),而")("和"("则不是。
一个字符串s的前缀是一个从位置1开始的子串。例如,对于s="(())()",有6个前缀。"(", "(", "()", "())", "())("和"()()"。
在你看来,一个整齐干净的房间s是一个括号序列,即。
整个字符串s是一个有规律的括号序列。
而且这个序列正好有k个前缀是有规律的(包括整个s本身)。
例如,如果k=2,那么"()() "就是一个整齐干净的房间。
你希望最多使用n个操作来使你的房间整洁干净。操作是一个接一个按顺序应用的。
可以保证答案的存在。请注意,你不需要最小化操作的数量:找到任何方法,在n个或更少的操作中实现所需的配置。
输入
第一行包含整数t(1≤t≤100)--输入的测试用例的数量。接着是t个测试用例。
测试用例的第一行包含两个整数n和k(1≤k≤n2,2≤n≤2000,n为偶数)--s的长度和所需的正则前缀数。
测试用例的第二行包含长度为n的s--给出的括号序列。它只包含'('和')'。
可以保证在给定的字符串中正好有n2个字符'('和正好n2个字符')'。
在输入的所有测试案例中,所有数值n的总和不超过2000。
输出
对每个测试案例打印一个答案。
在第一行打印整数m(0≤m≤n)--操作的数量。你不需要使m最小化,任何数值都是合适的。
在接下来的m行中打印操作的描述,每行应包含两个整数l,r(1≤l≤r≤n),代表s[l...r]=slsl+1...sr的单一反向操作。操作是一个接一个按顺序应用的。
所有运算后的最终s应该是有规律的,同时它应该正好是k个有规律的前缀(包括s)。
保证答案的存在。如果有几个可能的答案,你可以打印任何一个。
例子
InputCopy
4
8 2
()(())()
10 3
))()()()((
2 1
()
2 1
)(
输出拷贝
4
3 4
1 1
5 8
2 2
3
4 10
1 4
6 7
0
1
1 2
注意
在第一个例子中,最后的序列是"()()())",其中两个前缀是有规律的,"() "和"()()"。请注意,除了 "5 8 "以外的所有操作在例子的输出中都是无用的(它们不改变s)。
一个关于括号序列的规律,如果一个括号序列为偶数项.且(与)的个数相同,可以通过进行将区间[l,r]里的内容翻转,使其变为()()()...((...))这样的形式.
所以根据题意先构造出一个为k个(),后全为((..))的形式即可,接下来暴力反转即可
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int n,k;
string s;
pair<int,int> ans[2005];
void rever(int l,int r)
{
for(int i = 0; i < (r - l +1)/2 ;i++)
{
swap(s[l + i],s[r - i]);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t--)
{
int cnt = 0;
cin >> n >> k;
cin >> s;
string res;
for(int i = 1; i < k; i++)
{
res += "()";
}
for(int i = 1; i <=(n - k*2)/2 + 1; i++)
res += "(";
for(int i = 1; i<=(n - k*2)/2 + 1; i++)
res +=")";
for(int i = 0;i < n ;i++)
{
int j = i;
while(s[j] != res[i])
{
j ++;
}
ans[++cnt].first = i + 1;
ans[cnt].second = j + 1;
rever(i,j);
}
cout << cnt <<endl;
for(int i = 1; i <= cnt;i ++)
{
cout <<ans[i].first <<" "<< ans[i].second <<endl;
}
}
}