标签:kmp codeforces
先上链接:http://codeforces.com/contest/454/problem/B
题意:给你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),布布扣,bubuko.com
codeforces round#259 div2 B题(KMP)
标签:kmp codeforces
原文地址:http://blog.csdn.net/u014325920/article/details/38398483