题目
题意:
你有一个由 构成的字符串,现在你可以让这些字符串里面互相看着的人转头,每一次可以选择多人转头,构造最后在 次转头后两两不会互相看向对面的方法。
思路:
我们先来看看能不能出现这个序列:
- 我们先来求最大值,最大值就是每一次只转一个人,这样可以达到最后。
- 最小值就是每一次最大的数量,因为每一次可以选择多个人转头,那么我们每一步都把互相看对方的转头,这样的次数就是最小的次数。
如果不在最大值和最小值的范围内,那么肯定就要输出
了。
然后就是如果输出这个序列,我们我们求出
值和最小值
中间有的差是多少,这一部分可以用只转一对来实现,这样补上这个差值,然后后面的每一次都输出最大的转头就行了,但是有一个需要注意的地方,代码中要将队列
剩个一,相当与这是将转头的最大输出,因为我们前面是直接减去
的。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
template <class T>
inline void read(T &ret) {
char c;
int sgn;
if (c = getchar(), c == EOF) return ;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
sgn = (c == '-') ? -1:1;
ret = (c == '-') ? 0:(c - '0');
while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return ;
}
inline void out(int x) {
if (x > 9) out(x / 10);
putchar(x % 10 + '0');
}
const int maxn = 3010;
char s[maxn];
int a[maxn];
veci v;
int main() {
int n, k;
read(n), read(k);
scanf("%s", s);
for (int i = 0; i < n; i++) {
if (s[i] == 'R') a[i] = 1;
else a[i] = 0;
}
queue<veci > q;
int Max = 0;
while (1) {
v.clear();
for (int i = 0; i < n - 1; i++) {
if (a[i] && !a[i + 1]) {
v.push_back(i);
swap(a[i], a[i + 1]);
i++;
}
}
if (v.size() == 0) break;
Max += v.size();
q.push(v);
}
if (k < q.size() || k > Max) {
printf("-1\n");
return 0;
}
int cnt = k - q.size();
while (!q.empty()) {
veci now = q.front();
q.pop();
while (now.size() > 1 && cnt > 0) {
cnt--;
printf("1 %d\n", now.back() + 1);
now.pop_back();
}
printf("%d ", now.size());
for (int i = 0; i < now.size(); i++) {
printf("%d ", now[i] + 1);
}
printf("\n");
}
}