CF-Round #623-div2-C题
C. Restoring Permutation
来了!一天的疲惫瞬间被原本以为会tle然后ac的代码瓦解。我的快乐,你懂了吗啊哈哈哈哈。
这是一个贪心题。贪心策略还是挺简单的。
题目大意:没错。这道题的题目我也理解了很久。。。完全忽视了permutation这个词。。。序列序列!!!连续的!!!让你找出字典序最小的序列。使得b[i] = min(a[2 * i - 1], a[2 * i]);
当初在第二个测试样例那里卡了半天??明明有可以得到序列啊?为啥输出-1。后来恨不得扇自己。。。关键词是序列!需要连续。
已知b[], 求a[]。
我们很容易知道a[2 * i - 1] = b[i];这个毫无疑问把。
现在我们就是要让a[2 * i]最小就行
最简单的方法:遍历
从b[i]开始遍历。遇到最小的就赋值就行。
这个地方我们记录一下得到的最大值maxx;
最后判断连续的时候:看maxx == 2 * n是否成立。
不成立就说明不连续。你发现了吗maxx必须为even.
所以就很简单啦~
代码部分:
#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e2 + 10;
int a[N];
int b[N << 1];
int vis[N << 1];
int main()
{
int t;
cin >> t;
while (t--)
{
mst(vis, 0);
int n;
int flag = 0;
int cnt = 0;
int maxx = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf ("%d", &a[i]);
b[i * 2 - 1] = a[i];
if (!vis[a[i]])
{
vis[a[i]] = 1;
}
else
{
flag = 1;
}
}
int k;
for (int i = 1; i <= n; i++)
{
k = a[i];
while (vis[k])
{
k++;
}
vis[k] = 1;
b[i * 2] = k;
if (maxx < k)
{
maxx = k;
}
}
if (maxx != 2 * n)
{
flag = 1;
}
if (flag)
{
cout << "-1\n";
}
else
{
for (int i = 1; i <= 2 * n; i++)
{
cout << b[i] << " ";
}
cout << endl;
}
}
return 0;
}