Codeforces 1333 D. Challenges in school №41

在这里插入图片描述
在这里插入图片描述

题意:

给定一个长度为 n n 且由字符 L , R L,R 构成的字符串,每轮操作中,你都能选择任意对相邻的 R L RL ,将其变为 L R LR ,询问能否正好用 k k 轮将字符串中的 L L 全部移动至左端, R R 全部移动至右端。

每一轮操作我们都贪心地将所有能够交换的位置互换,统计最少需要 c n t cnt 轮才能完成交换,并统计交换的总次数 s u m sum ,如果 k [ c n t , s u m ] k∈[cnt,sum] 那么就可以给出交换方案,因为我们能将某一轮中的操作拆开来,最多能够拆成 s u m sum 轮。

AC代码:

const int N = 3010;
vector<int> v[N];
char s[N];
int n, k;
int cnt, sum;
bool flag;
int main()
{
	sdd(n, k);
	ss(s + 1);
	cnt = 0;
	sum = 0;
	while (1)
	{
		flag = false;
		cnt++;
		rep(i, 1, n)
		{
			if (s[i] == 'R' && s[i + 1] == 'L')
			{
				flag = true;
				v[cnt].pb(i);
			}
		}
		for (auto it : v[cnt])
			swap(s[it], s[it + 1]);
		sum += v[cnt].size();
		if (!flag)
			break;
	}
	cnt--;
	if (k < cnt || k > sum)
	{
		puts("-1");
		return 0;
	}
	rep(i, 1, cnt)
	{
		while (!v[i].empty() && k > cnt - i + 1)
		{
			printf("1 %d\n", v[i].back());
			v[i].pop_back(); //pop_back()可以删除最后一个元素.
			k--;
		}
		if (!v[i].empty())
		{
			printf("%d", v[i].size());
			for (auto it : v[i])
				printf(" %d", it);
			printf("\n");
			k--;
		}
	}
	return 0;
}
发布了786 篇原创文章 · 获赞 460 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/105403483