2010-11-21 22:46:04
题目地址:http://acm.fzu.edu.cn/problem.php?pid=1664
通过这道题目学会了使用 合并排序(MergeSort) 与 快速排序(QuickSort),可是关于一个算法的最坏时间复杂度与平均时间复杂度仍然是+_++_+的,MergeSort最坏复杂度与平均复杂度为O(nlogn),QuickSort最坏复杂度为O(n^3),平均复杂度为O(nlogn)。。。
我的MergeSort错误代码:
#include<stdio.h>
int Merge(int *p1,int *p2,int n,int mid)
{
int i,j,k;
k=i=0; j=mid;
while(i<mid&&j<n)
{ if(*(p1+i)>*(p2 +j)) /// p2应该为 p1
{ *(p2+k)=*(p1+j); j++;}
else {*(p2+k)=*(p1+i);i++;}
k++;
}
if(i==mid)
for(;j<n;j++,k++) *(p2+k)=*(p1+j);
else
for(;i<mid;i++,k++) *(p2+k)=*(p1+i);
return 0;
}
int MergeSort(int *p1,int *p2,int n)
{
int mid=n/2;
if(n>1)
{
MergeSort(p2,p1,mid);
MergeSort(p2+mid,p1+mid,n-mid);
Merge(p1,p2,n,mid);
}
return 0;
}
int main()
{
int n,k,flag,i,a[10001]={0},b[10001]={0};
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=1;i<n+1;i++)
{scanf("%d",&a[i]); b[i]=a[i];}
if(n%2) MergeSort(a,b,n+1);
else MergeSort(a+1,b+1,n); //// 其实不必考虑到序列个数n是偶数还是奇数
flag=1;
for(i=n-1;i>0;i--)
if(a[i]!=a[i+1])
{
flag++;
if(flag>=k) break;
} ///// 该程序段应该在k>1的情况下才执行的,否则k=1时,执行完该程序段后flag=2
if(flag>=k)
{
printf("%d",a[i]);
for(i++;i<n+1;i++)
if(a[i]!=a[i-1])
printf(" %d",a[i]); //// 由上面可知,应分k=1与k>1两种情况,k=1输出a[n],k>1时,执行该程序段
}
else printf("-1");
printf("/n");
}
return 0;
}
尽管改了上述错误后,似乎仍是不能AC,不知道哪里还有错,最后不考虑序列个数n的奇偶性,然后经过相关调整后,终于是AC 了
#include<stdio.h>
int Merge(int *p1,int *p2,int n,int mid)
{
int i,j,k;
k=i=0; j=mid;
while(i<mid&&j<n)
{ if(*(p1+i)>*(p1+j))
{ *(p2+k)=*(p1+j); j++;}
else {*(p2+k)=*(p1+i);i++;}
k++;
}
if(i==mid)
for(;j<n;j++,k++) *(p2+k)=*(p1+j);
else
for(;i<mid;i++,k++) *(p2+k)=*(p1+i);
return 0;
}
int MergeSort(int *p1,int *p2,int n)
{
int mid=n/2;
if(n>1)
{
MergeSort(p2,p1,mid);
MergeSort(p2+mid,p1+mid,n-mid);
Merge(p1,p2,n,mid);
}
return 0;
}
int main()
{
int n,k,flag,i,a[10000],b[10000];
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=0;i<n;i++)
{scanf("%d",&a[i]); b[i]=a[i];}
MergeSort(a,b,n);
flag=1; i=n-1;
while(flag<k&&i>0) /////+_+刚开始是i>=0又得到了个WA +_+
{
i--;
if(b[i]!=b[i+1]) flag++;
}
if(flag>=k)
{
printf("%d",b[i]);
for(i++;i<n;i++)
if(b[i]!=b[i-1])
printf(" %d",b[i]);
}
else printf("-1");
printf("/n");
}
return 0;
}
下面是用了QSort 的AC代码:
#include<stdio.h>
void swap(int *p1,int *p2)
{
int temp;
temp=*p1;*p1=*p2;*p2=temp;
}
int FindPivot(int *p,int n)
{
int i;
for(i=1;i<n;i++)
{ if(*p>*(p+i)) return 0;
if(*p<*(p+i)) return i;
}
return -1;
}
int Partition(int *p,int n,int Pivot)
{
int left=0,right=n-1;
do
{
swap(p+left,p+right);
while(*(p+left)<Pivot) left++;
while(*(p+right)>=Pivot) right--;
} while(left<right);
return left;
}
void QSort(int *p,int n)
{
int PivotIndex,k;
if(n>1)
{
PivotIndex=FindPivot(p,n);
if(PivotIndex>-1)
{
k=Partition(p,n,*(p+PivotIndex));
QSort(p,k);
QSort(p+k,n-k);
}
}
}
int main()
{
int n,k,flag,i,a[10000];
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
QSort(a,n);
flag=1;
if(n>1&&k>1)
{
for(i=n-2;i>=0;i--)
if(a[i]!=a[i+1])
{
flag++;
if(flag>=k) break;
}
}
if(flag>=k)
{
if(k==1) printf("%d",a[n-1]);
else
{
printf("%d",a[i]);
for(i++;i<n;i++)
if(a[i]!=a[i-1])
printf(" %d",a[i]);
}
}
else printf("-1");
printf("/n");
}
return 0;
}