题解 P7852 「EZEC-9」Yet Another Easy Problem
虽说这次月赛比较阴间,但这道题并不是想象的那么难(虽然月赛中这T1花了我半小时QwQ)
我们需要逆向推理一下,对于一个长度为
对于每一次操作,肯定是把后面的最小数移到前面去,例如:第一次操作把
现在,我们要做的就是把这个最终排列还原成
第一种:由于我们会把
第一种方法的代码如下:
#include <bits/stdc++.h>
using namespace std;
int T, n, m;
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &m);
printf("%d ", n);//先输出n
for (int i = 1; i <= min(m, n - 1); i++)//min的作用是来特判n=m
printf("%d ", i);//输出1-m
for (int i = n - 1; i >= m + 1; i--)
printf("%d ", i);//输出n-1到m+1
printf("\n");//记得换行
}
return 0;
}
第二种:这种方法有点小玄学,是我比赛时想到的。
构造好最终排列后,我们要进行
个人还是推荐用第一种方法,第二种实在不好想到。
第二种方法的代码如下:
#include <bits/stdc++.h>
using namespace std;
int T, n, m;
int a[100010];
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
a[i] = i;
for (int i = m + 1; i <= n; i++)//先构造最终排列
a[n - i + m + 1] = i;
for (int i = m; i >= 1; i--)//从m项开始一次次交换
swap(a[i], a[n + i - m]);
for (int i = 1; i <= n; i++)
printf("%d ", a[i]);
printf("\n");//记得换行
}
return 0;
}
如果你觉得这篇题解还不错,点个赞再走呗OwO