这次是Dreamoon大佬出的题,毫无意外掉分了QAQ,第一次被hack,收获很大 /偷看 ,自己还要努力!!
A. Dreamoon and Ranking Collection
题目大意:给你n个数和一个数k,让插入k个数,使得1-v连续,输入最大数v。
题解:输入的同时使用vis做标记,然后从1遍历一遍,当vis没有被标记的时候,就使用一次插空的机会。
坑点 :你要用当k+1次时再break,然后ans-1。如果你从k就跳出,你可能从后面又连续了。(我就是这样被hack了)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
bool vis[300];
int main()
{
ios::sync_with_stdio(false);
int t, n, x, y, temp = 0;
int a[105];
cin >> t;
while (t--)
{
cin >> n >> x;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++)
{
cin >> y;
vis[y] = 1;
}
int ans = 0, cnt = 0;
for (int i = 1;; i++)
{
if (vis[i] == 0)
++cnt;
ans = i;
if (cnt == x + 1)
break;
}
cout << ans-1 << endl;
}
return 0;
}
B. Dreamoon Likes Permutations
题目大意:给你n个数从a1到an。现在让你找到长度为len和n-len长的序列,使得序列中包含1到len和1到n-len的所有数。你不能打乱原来的序列顺序。若能找到输出这两个序列的长度和总共种类数。
题解: 我用的前n项和的求和公式优化和bool数组桶排的思想标记1到len的所有数。
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
int t, n;
bool vis[200005];
ll a[200005];
ll sum[200005];
vector<int> ans;
#define rep(i, a, b) for (int i = a; i <= b; i++)
int main()
{
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
sum[0] = 0;
cin >> n;
rep(i, 1, n)
{
cin >> a[i];
sum[i] = sum[i - 1] + a[i]; //记录前缀和
}
ans.clear();
bool flag1 = 0, flag2 = 0;
for (ll i = 1; i < n; i++)
{
ll temp = (1 + i) * i / 2;
ll temp2 = (1 + n - i) * (n - i) / 2;
if (sum[i] == temp && sum[n] - sum[i] == temp2) //利用等差求和和前n项和公式
{
memset(vis, 0, sizeof(vis));
flag1 = flag2 = 0;
for (int j = 1; j <= i; j++) //在第一段1-i的长度进行标记a[i]的所有数字
{
if (vis[a[j]] == 0)
vis[a[j]] = 1;
else
{
flag1 = 1;
break;
}
}
if (flag1 == 0)
{
for (int j = 1; j <= i; j++) //查找1-i长度的序列是否又1-i中所有的数
{
if (vis[j] == 0)
{
flag1 = 1;
break;
}
}
}
if (flag1 == 0)
{
memset(vis, 0, sizeof(vis));
for (int j = i + 1; j <= n; j++) //同理第二段也是
{
if (vis[a[j]] == 0)
vis[a[j]] = 1;
else
{
flag2 = 1;
break;
}
}
if (flag2 == 0)
{
for (int j = 1; j <= n - i; j++)
{
if (vis[j] == 0)
{
flag2 = 1;
break;
}
}
if (flag2 == 0)
ans.push_back(i);
}
}
}
}
cout << ans.size() << endl; //输出答案
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " " << n - ans[i] << endl;
}
return 0;
}