先上链接:http://codeforces.com/contest/454/problem/B
B. Little Pony and Sort by Shift
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
One day, Twilight Sparkle is interested in how to sort a sequence of integers a1,?a2,?...,?an in
non-decreasing order. Being a young unicorn, the only operation she can perform is a unit shift. That is, she can move the last element of the sequence to its beginning:
a1,?a2,?...,?an?→?an,?a1,?a2,?...,?an?-?1.
Help Twilight Sparkle to calculate: what is the minimum number of operations that she needs to sort the sequence?
Input
The first line contains an integer n (2?≤?n?≤?105).
The second line contains n integer numbers a1,?a2,?...,?an (1?≤?ai?≤?105).
Output
If it‘s impossible to sort the sequence output -1. Otherwise output the minimum number of operations Twilight Sparkle needs to sort it.
Sample test(s)
input
2 2 1
output
1
input
3 1 3 2
output
-1
input
2 1 2
output
0
题意:给你n个数,要你给这n个数排序,排序成非递减的序列。但是排序的规则是每次只能把序列的最后一个数放到最前面。求组成非递减序列所需要最少的次数。如果不能组成,则输出-1.
这道题我非常神奇的想到了用KMP去做,竟然过了。。。
先给出思路:假设能够排序成非递减序列,最多执行n次。那我就让它先执行n次。
则我能让原始序列变成 2*n的长度 假如序列之前为 4 1 2 3 ,执行n次我可以假设它变成了 4 1 2 3 4 1 2 3。
然后用kmp算法找到 1 2 3 4的位置(当然是靠后面的位置),然后记录位置d, n - d就是它的执行次数,如果没有匹配到,就不能变成之前的样子。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define maxn 100005 int ans[maxn], v[maxn], va[maxn + maxn]; int next[maxn]; int n, d; using namespace std; void getnext() { int j = 0; int k = -1; next[0] = -1; while(j < n) { if(k == -1 || v[j] == v[k]) { ++k; ++j; next[j] = k; } else k = next[k]; } } void kmp() { int i = 0, j = 0; while(i < n + n) { if(j == -1 || va[i] == v[j]) { ++i; ++j; } else j = next[j]; if(j == n) d = i - j,j = next[j]; } } int main() { while(scanf("%d", &n) != EOF) { for(int i = 0; i < n; ++i) { scanf("%d", &ans[i]); v[i] = ans[i]; } d = -1; sort(v, v + n); for(int i = 0; i < n; ++i) va[i] = va[i + n] = ans[i]; /** printf("ans = \n"); for(int i = 0;i < n;++i) printf("%d ",ans[i]); printf("\n"); for(int i = 0;i < n;++i) printf("%d ",v[i]); printf("\n"); for(int i = 0;i < n+n;++i) printf("%d ",va[i]);printf("\n"); **/ getnext(); kmp(); if(d == -1) printf("%d\n",d); else printf("%d\n",n - d); } return 0; }
codeforces round#259 div2 B题(KMP)