Codeforces 1838 B Minimize Permutation Subarrays解析

该问题是一个关于数组操作的构造题,目标是找到两个下标i和j,通过交换这两个位置的元素来使数组的连续子序列形成的排列组合数量尽可能少。关键策略是避免出现1和2相邻,以及将最大值n置于1和2之间,以防止特定长度的排列组合出现。
摘要由CSDN通过智能技术生成

题目地址

https://codeforces.com/problemset/problem/1838/B

题目抽象

给一个长度为 n 的数组 a a a,它是 1 1 1 n n n 数字的排列组合,要求你找到两个下标 i i i j j j,使得交换 a i a_i ai a j a_j aj 后, a a a 的连续子序列所能形成的排列组合越少越好

数据范围:
3 ≤ n ≤ 2 ⋅ 1 0 5 3\le n \le 2\cdot 10^5 3n2105
1 ≤ a i ≤ n 1\le a_i \le n 1ain

题目类型

构造

解题思路

首先,不管怎么交换, [ 1 ] , [ 1 … n ] [1], [1 \dots n] [1],[1n] 这两个排列组合一定会存在,只选1和全选
那么我们的目的就是让其他的组合尽可能不出现
我们来看最容易出现的排列组合是 [ 1 , 2 ] [1,2] [1,2],所以 1 1 1 2 2 2 只要不挨在一起,就不会出现 [ 1 , 2 ] [1,2] [1,2]
对于长度为 k , n > k > 2 k, n > k > 2 k,n>k>2 的排列组合,它的子序列一定要包含 1 1 1 2 2 2,且 1 , 2 1,2 1,2 之间不能包含比 k k k 大的数字,所以如果我们将最大的 n n n 放在 1 , 2 1,2 1,2 之间,那么一定无法形成长度为 k k k 的排列组合
答案就很简单
找到 1 , 2 , n 1,2,n 1,2,n 的位置,判断他们的位置,把 n n n 放到 1 1 1 2 2 2 之间

代码

#include <bits/stdc++.h>
using namespace std;

int n;
void solve() {
  cin >> n;
  int one, two, mx;
  for (int i = 1, a; i <= n; i ++) {
    cin >> a;
    if (a == 1) one = i;
    else if (a == 2) two = i;
    else if (a == n) mx = i;
  }
  if (mx > one && mx > two) {
    cout << mx << ' ' << max(one, two) << endl;
  } else if (mx < one && mx < two) {
    cout << mx << ' ' << min(one, two) << endl;
  } else {
    cout << "1 1" << endl;
  }
}
int main() {
  int T; cin >> T; while (T--) solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值