codeforces round#259 div2 B题(KMP)

先上链接: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)

时间: 2024-10-03 22:53:35

codeforces round#259 div2 B题(KMP)的相关文章

Codeforces Round #259(div2)C(数学期望)

数学题. 关键是求最大值为k时有多少种情况,结果是kn-(k-1)n-1.可以这么想:每一次都从1至k里选,共kn种,这里需要再减去每一次都从1至k-1里面选的情况.当然也可以分类计数法:按出现几次k来分类,然后逆着用一下二项式定理得出结论. 整个的期望是Σk(kn-(k-1)n-1)/mn,其中k=1......n. 这里的技巧在于:由于n<=105,   kn显然会RE,那么就先把分母除上,每次算一个小于1的浮点数的n次方,肯定不会RE.C++中乘方用pow函数算是很快的. #include

codeforces round #499(div2) 做题记录

A. Stages 题意: 给你n个字母,你要选k个,你选择的相邻两个字母在字母表中必须满足中间至少隔一个字母,每个字母的权值是c-'a'+1,求最小权值和. k<=n<=50 题解:贪心,从前向后扫,满足题意的就加进去就可以了 1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 55 4 using namespace std; 5 int n,k; 6 char s[maxn]; 7 int w[max

codeforces round 422 div2 补题 CF 822 A-F

A I'm bored with life 水题 #include<bits/stdc++.h> using namespace std; typedef long long int LL; const LL N=1,M=1,MOD=1; int main() {//freopen("t.txt","r",stdin); ios::sync_with_stdio(false); LL a,b; scanf("%I64d%I64d",&

codeforces round 418 div2 补题 CF 814 A-E

A An abandoned sentiment from past 水题 #include<bits/stdc++.h> using namespace std; int a[300],b[300],n,k; bool cmp(int a,int b) { return a>b; } int main() {//freopen("t.txt","r",stdin); scanf("%d%d",&n,&k); f

codeforces Round #259(div2) 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-decreas

codeforces round 421 div2 补题 CF 820 A-E

A Mister B and Book Reading  O(n)暴力即可 #include<bits/stdc++.h> using namespace std; typedef long long int LL; const LL N=1,M=1,MOD=1; int main() {//freopen("t.txt","r",stdin); int c,v0,v1,a,l; scanf("%d%d%d%d%d",&c,&

codeforces round #324(div2) E题 Anton and lra

这道E题真的毒瘤啊,看完题解后还花了三小时AC... 主要是让这个位置上的数字如果要换到前面,那么前面至少有一个要到这个位置上,交换就好啦. 交换之后更新位置,直到这个数字被交换到指定位置. 为了 简化操作,我们可以把所有目标序列(s列)中数字出现的位置替换p序列中的数字,这样目标序列转化成一个1到n的序列 #include<bits/stdc++.h> using namespace std; int p[2001]; int s[2001]; int pos[2001]; int tot;

codeforces Round #259(div2) C解题报告

C. Little Pony and Expected Maximum time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Twilight Sparkle was playing Ludo with her friends Rainbow Dash, Apple Jack and Flutter Shy. But she kept

codeforces Round #259(div2) D解题报告

D. Little Pony and Harmony Chest time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output Princess Twilight went to Celestia and Luna's old castle to research the chest from the Elements of Harmony