Codeforces Round 967 (Div. 2)
A. Make All Equal
思路:观察题目,其实不难发现,保留一种数字之后,删除操作就可以删除任意其余数字。因此我们只需桶排序出数量最多的那一个数字的数量 x,最后的答案就是 n - x。
代码:
/*
* @OJ:
* @ID:
* @Author: ZhangChao
* @Date: 2024-08-15 17:35:14
*/
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 5e5 + 5, P = 13331;
int cnt[N], n;
void solve()
{
int T = 1;
cin >> T;
while (T--)
{
memset(cnt, 0, sizeof(cnt));
int mx = 0;
cin >> n;
for (int i = 1, x; i <= n; i++)
{
cin >> x;
cnt[x]++;
mx = max(mx, cnt[x]);
}
cout << n - mx << endl;
}
}
signed main()
{
ios;
solve();
return 0;
}
B. Generate Permutation
思路:题目要求构造出任意一种符合条件的排列,要求两种打字机回车操作数相同。观察回车操作,我们发现对于 i,如果 i - 1 在其左边,第一台打字机需要执行一次回车操作,反之,第二台打字机需要执行一次。因此,我们对于 a1a2a3...an ,可以构造出 an-1...a2a1a3...an,可以证明这样的序列是符合条件的。
代码:
/*
* @OJ:
* @ID:
* @Author: ZhangChao
* @Date: 2024-08-15 17:35:14
*/
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 5e5 + 5, P = 13331;
int n, a[N];
void solve()
{
int T = 1;
cin >> T;
while (T--)
{
cin >> n;
if (n % 2 == 0)
{
cout << -1 << endl;
}
else
{
int mid = n / 2 + 1;
a[mid] = 1;
int tmp = n - 1;
int cnt = 1, num = 1;
while (tmp)
{
a[mid + cnt] = ++num;
a[mid - cnt] = ++num;
cnt++;
tmp -= 2;
}
for (int i = 1; i <= n; i++)
{
cout << a[i] <<" ";
}
cout << endl;
}
}
}
signed main()
{
ios;
solve();
return 0;
}
C. Guess The Tree
思路:可以发现,查询 a 和 b 将返回 a 和 b 之间路径的中点。如果路径长度为奇数,则会返回两个中心节点中更靠近 a 的节点。因此,我们可以在 log 的时间复杂度下,找到 a 任意一边。
代码:交互题,代码省略。
D. Longest Max Min Subsequence
思路:可以想到贪心的去求解,不让假设我们所要构建的序列为 b,长度为 m,对于 bi,我们需要找到一个合适的范围 [a,b],满足对于 [b+1,n],序列 a 中不同元素的数量为 m - i 个。为了解决这个问题,我们引入 l 数组记录每个元素最后的坐标。由此,可以将范围中的 b 转化为 l1 - ln 中的最小值。同时,我们观察到 a 和 b 都是非严格递增的。因此,可以借助优先队列或单调栈在 nlogn 的时间复杂度下解决。
代码:
/*
* @OJ:
* @ID:
* @Author: ZhangChao
* @Date: 2024-08-15 17:35:14
*/
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 5e5 + 5, P = 13331, INF = 1e15;
int l[N], a[N], n, b[N];
bool used[N];
struct node
{
int val, idx;
bool operator<(const node &u) const
{
if (val != u.val)
return val < u.val;
return idx > u.idx;
}
};
void solve()
{
int T = 1;
cin >> T;
while (T--)
{
priority_queue<int, vector<int>, greater<int>> lx;
priority_queue<node> mx, mi;
cin >> n;
for (int i = 1; i <= n; i++)
l[i] = INF,used[i] = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
l[a[i]] = i;
}
for (int i = 1; i <= n; i++)
{
lx.push(l[i]);
}
for (int i = 1; i <= lx.top(); i++)
{
mx.push({a[i], i});
mi.push({-a[i], i});
}
int i = 1, cnt = 0;
while (!mi.empty())
{
// 1. [i+1,minlx]
if (!(cnt & 1))
{
b[++cnt] = mx.top().val;
used[b[cnt]] = 1;
i = mx.top().idx + 1;
// mx.pop();
}
else
{
b[++cnt] = -mi.top().val;
used[b[cnt]] = 1;
i = mi.top().idx + 1;
// mi.pop();
}
while (!lx.empty() && lx.top() != INF && used[a[lx.top()]])
{
int j = lx.top();
lx.pop();
for (int k = j + 1; k <= min(lx.top(), n); k++)
{
mx.push({a[k], k});
mi.push({-a[k], k});
}
}
while (!mx.empty() && (used[mx.top().val] || mx.top().idx < i))
mx.pop();
while (!mi.empty() && (used[-mi.top().val] || mi.top().idx < i))
mi.pop();
}
cout << cnt << endl;
for (int i = 1; i <= cnt; i++)
{
if (i == cnt)
cout << b[i];
else
cout << b[i] << " ";
}
cout << endl;
}
}
signed main()
{
ios;
solve();
return 0;
}

浙公网安备 33010602011771号