0%

Codeforces 454B 解题报告

题意简述

给定一个数字 \(n(2 \leq n \leq 10 ^ 5)\) 和一个长度为 \(n\) 的序列(序列中的每个元素 \(1 \leq a _ i \leq 10 ^ 5\)),只允许一种操作:将序列尾端的元素移动到序列的头部。问能否使用这种操作让序列中的元素非递减。如果能,输出最少的操作次数,如果不能,输出 \(-1\)

时间限制:1s 空间限制:256MB

题目链接

Codeforces 454B

题解

可以发现一个规律:能够被这种方式排序的序列必然满足以下条件:该序列可以被划分为前后两个序列,两个序列均为非递减序列,后序列中的每个元素均小于等于前序列头部的元素。此时对该序列排序的代价为后序列的长度。(后序列可以为空,此时答案为 \(0\) )由于要求操作次数最小,所以后序列的大小尽量小。根据以上规律检查整个序列即可得到答案。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
bool reCounted = false;
int result = 0,lastValue = -1,firstValue = -1;
for(int i = 0;i < n;i++) {
int tmpValue;
cin >> tmpValue;
if(lastValue == -1) {
lastValue = tmpValue;
firstValue = tmpValue;
continue;
}
if(!reCounted) {
if(tmpValue < lastValue) {
if(tmpValue <= firstValue) {
reCounted = true;
result++;
}else {
result = -1;
break;
}
}
}else {
if(tmpValue < lastValue || tmpValue > firstValue) {
result = -1;
break;
}else {
result++;
}
}
lastValue = tmpValue;
}
cout << result << endl;
return 0;
}