题意:quick sort中,pivot会将array分成两个sub array,worst case是一个sub array为空,另一个sub array 是N-1个。给定一个array(1~N全排列),问pivot是否一直都是worst case pivot。
本来感觉直接模拟quick sort时间是够的,但最后large input内存爆了。。sample solution说需要手动增加stack容量。。这都可以==
对于 array A[0,1,...,N-1],如果一直是worst case pivot, pivot变化的次序是(N-1)/2,(N-1)/2+1,(N-1)/2-1,(N-1)/2+2,...when N is even。对应的操作次序是+1,-2,+3,-4,...。对于N is odd,pivot变化次序是(N-1)/2,(N-1)/2-1,(N-1)/2+1,(N-1)/2-2,...对应的操作次序是-1,+2,-3,+4,...emmm其实这个规律我自己并木有发现。
如果选的是worst case pivot,那么A[pivot]是当前sub array中最大或者最小的值。因为A是1~N的全排列,可以维护一个当前最大值maxi和当前最小值mini。初始值maxi=N,mini=1.如果选到的A[pivot]==maxi(是最大值),更新maxi=maxi-1。如果选到的A[pivot]==mini(是最小值),更新mni=mini+1.
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<windows.h>
using namespace std;
//Kcikstart 2017 Round F Problem A. Kicksort
const int maxn=10010;
int T;
int N;
int A[maxn];
int ans;
int main()
{
// freopen("input.txt","r",stdin);
freopen("A-large-practice.in","r",stdin);
freopen("A.txt","w",stdout);
cin>>T;
for(int ca=1;ca<=T;ca++)
{
memset(A,0,sizeof(A));
ans=1;
scanf("%d",&N);
for(int i=0;i<N;i++)
{
scanf("%d",&A[i]);
}
int maxi=N;
int mini=1;
int pivot=(N-1)/2;
for(int i=0;i<N-1;i++)
{
if(A[pivot]!=maxi&&A[pivot]!=mini)
{
ans=0;
break;
}
if(A[pivot]==maxi)
{
maxi-=1;
}
if(A[pivot]==mini)
{
mini+=1;
}
if(N%2==0)
{
if(i%2==0)
{
pivot+=i+1;
}
else
{
pivot-=i+1;
}
}
else
{
if(i%2==0)
{
pivot-=i+1;
}
else
{
pivot+=i+1;
}
}
}
printf("Case #%d: %s\n",ca,ans==0?"NO":"YES");
}
return 0;
}