专栏文章
题解:P13492 【MX-X14-T2】反转时光
P13492题解参与者 6已保存评论 6
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @miopqvld
- 此快照首次捕获于
- 2025/12/02 23:08 3 个月前
- 此快照最后确认于
- 2025/12/02 23:08 3 个月前
前言:这道题目的数据真的很水。
进入正题:
一.我们怎么确定这道题是什么算法?
我们可以先看 的数据:
对于 的数据,
,保证 是一个 的排列。
由此,我们可知暴力是会超时的,通过此题要用 或 的做法,考虑数学或二分。但这道题不满足使用二分的单调性,所以这道题我们使用数学。
二.如何得出规律?
我们可以针对样例:
对于样例一的解释:这明显是一个连续上升的序列,不用交换,所以 为 。同样的,只要序列满足连续上升,则 为 。
对于样例二的解释:这个序列有两个依次上升的子序列,我们可以交换这两个子序列,使它变得有序,所以 的值为 。同样的,序列只要满足有两个依次上升的子序列,我们的 就等于 。(注:这两个序列一定是依次上升的,否则就不能输出 。)
对于样例三的解释:对于这个完全无序的序列,我们可以输出 ,可以证明 是最小的 ,我们只需要每次将最大值、次大值、次次大值......依次找出来,将它的左边变成序列一,本身变成序列二,右边变成序列三,将序列一和序列二交换,就可以将最大值、次大值、次次大值......依次放在序列的左边,也就是说,对于一个长度为 的完全无序的序列,最多进行 次操作,就可以将它变成一个有序的序列,以下是例子:
对于序列:、、、,我们可以很容易发现它是完全无序的,我们可以做出以下操作:
-
交换 、 和 得序列 、、、。
-
交换 和 得序列 、、、。
-
交换 、 和 得序列 、、、。
-
交换 、、 和 得序列 、、、。
综上,我们的 最小是 。
三.代码
CPP#include<bits/stdc++.h>
using namespace std;
int n,a[100005],l;
bool check(int r){//判断 k 是否是 1 或 2。
for(int i=r;i<n;i++){
if(a[i]!=a[i+1]-1){
return 0;
}
}
for(int i=1;i<r-1;i++){
if(a[i]!=a[i+1]-1){
return 0;
}
}
//以上是遍历序列,看看它是否满足样例二的格式。
return 1;//满足返回 1。
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==1){
l=i;//记录 1 的位置,遍历的时候有一个起始点。
}
}
if(check(l)&&l==1){//特判,如果它是样例一的格式,输出 1。
cout<<1;
}
else if(check(l)){//否则如果它满足有两个依次上升的子序列,输出 2。
cout<<2;
}
else{//如果它是完全无序的序列,输出 3。
cout<<3;
}
return 0;
}
相关推荐
评论
共 6 条评论,欢迎与作者交流。
正在加载评论...