202512-1 数字移动
题目描述
小 A 有一个包含 个正整数的序列 ,序列 恰好包含 对不同的正整数。形式化地,对于任意 ,存在唯一一个 满足 。
小 A 希望每对相同的数字在序列中相邻,为了实现这一目的,小 A 每次操作会选择任意 ,将当前序列的第 个数字移动到任意位置,并花费对应数字的体力。
例如,假设序列 ,小 A 可以选择 ,将 移动到 的后面,此时序列变为 ,耗费 点体力。小 A 也可以选择 ,将 移动到 的前面,此时序列变为 ,花费 点体力。
小 A 可以执行任意次操作,但他希望自己每次花费的体力尽可能小。小 A 希望你能帮他计算出一个最小的 ,使得他能够在每次花费的体力均不超过 的情况下令每对相同的数字在序列中相邻。 输入格式
第一行一个正整数 ,代表序列长度,保证 为偶数。
第二行包含 个正整数 ,代表序列 。且对于任意 ,存在唯一一个 满足 。
数据保证小 A 至少需要执行一次操作。
输出格式
输出一行,代表满足要求的 的最小值。
样例输入 1
61 2 1 3 2 3样例输出 1
2提示
对于 的测试点,保证 。
对于所有测试点,保证 。
代码解析
题目意思是移动数字让相同的数字相邻,每次移动某个数字,就会耗费对应数字的体力,也就是说我们要尽可能移动小的数字,题目求的是最小的 。
二分答案解题,这道题满足二分答案的条件,我们可以二分 ,判断是否能够在移动的数字不超过 的情况下令每对相同的数字在序列中相邻。那么
check()函数中,我们需要遍历序列,找出所有大于 的数字,判断他们是否相邻,如果有不相邻的,就说明需要移动,就返回false,如果所有大于 的数字都相邻,就返回true。
#include <iostream>using namespace std;int a[100005], n, m;bool check(int mid) { int lst = 0; for (int i = 1; i <= n; i++) { if (a[i] <= mid) continue; if (lst == a[i]) lst = 0; else if (a[i] > mid && lst > mid) return false; else lst = a[i]; } return true;}
int main() {
cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; m = max(m, a[i]); } int mid, l = 1, r = m; while (l < r) { mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid + 1; } cout << r;
return 0;}202512-2 相等序列
题目描述
小 A 有一个包含 个正整数的序列 。小 A 每次可以花费 个金币执行以下任意一种操作:
- 选择序列中一个正整数 (),将 变为 , 为任意质数;
- 选择序列中一个正整数 (),将 变为 , 为任意质数,要求 是 的倍数。
小 A 想请你帮他计算出令序列中所有整数都相同,最少需要花费多少金币。 输入格式
第一行一个正整数 ,含义如题面所示。
第二行包含 个正整数 ,代表序列 。
输出格式
输出一行,代表最少需要花费的金币数量。
样例输入 1
510 6 35 105 42样例输出 1
8提示
对于 的测试点,保证 。
对于所有测试点,保证 。
代码解析
等待更新
陕公网安备61010302001363号