【問題】請教兩題~


Recommended Posts

tioj 的1167題..

http://tioj.redirectme.net:8080/JudgeOnline/showproblem?problem_id=1167

和1287題

http://tioj.redirectme.net:8080/JudgeOnline/showproblem?problem_id=1287

兩題我都是同樣的問題~Time Limit Exceed

我都是用快速排序去找的~怎會超出時間呢?難道有更快的方法?還是我快速排序有寫錯?

以後是我寫的快速排序的程式碼

void sort(int x[],int left,int right)

{

int i,j,temp,k;

if(left<right)

{

i=left+1;

j=right;

k=x

;

do

{

while(x<k)

i++;

while(x[j]>k)

j--;

if(i<j)

{

temp=x; x=x[j]; x[j]=temp;

}

} while(i<j);

temp=x

; x

=x[j]; x[j]=temp;

sort(x,left,j-1);

sort(x,j+1,right);

}

}

感謝~xd

鏈接文章
分享到其他網站

哈,

我找到了!

要這樣才對唷!

void sort(int x[],int left,int right)

{

int i,j,temp,k;

if(left<right)

{

i=left+1;

j=right;

k=x

;

do

{

while(x<=k)

i++;

while(x[j]>k)

j--;

if(i<j)

{

temp=x; x=x[j]; x[j]=temp;

}

} while(i<j);

temp=x

; x

=x[j]; x[j]=temp;

sort(x,left,j-1);

sort(x,j+1,right);

}

}

錯的地方已經用紅色標起來!

如果沒等號的話,

有時候會導致無窮迴圈!!!

當然就TLE啦!

其實我跟quicksort不熟,

如果有高手發現還有錯,或有更好寫法歡迎指教。

SORRY,問題真的是出在quicksort上!

不過下次還是全部Po上來比較保險。

鏈接文章
分享到其他網站

..不過腳踏車的還是沒過呢~= =

#include <stdio.h>

#include <stdlib.h>

void sort(int x[],int left,int right)

{

int i,j,temp,k;

if(left<right)

{

i=left+1;

j=right;

k=x

;

do

{

while(x<=k)

i++;

while(x[j]>k)

j--;

if(i<j)

{

temp=x; x=x[j]; x[j]=temp;

}

} while(i<j);

temp=x

; x

=x[j]; x[j]=temp;

sort(x,left,j-1);

sort(x,j+1,right);

}

}

int x[1000000];

int main(void)

{

int n,i,j,k;

while(scanf("%d%d",&n,&k)!=EOF)

{

if(n==0||k==0)

break;

for(i=0;i<n;i++)

scanf("%d",&x);

sort(x,0,n-1);

printf("%d\n",x[n-k]);

}

return 0;

}

以上為程式碼~感恩xd

鏈接文章
分享到其他網站

我懷疑quicksort還是有錯

而且我用C++內建函式庫的qsort就AC了= =

有沒有高手可以講解一下,

我怕我會說錯......

對了,

你叫ignored對不對?

內建函式庫寫法:

#include <stdio.h>

#include <cstdlib> //qsort所在函式庫(記得改!!!)

int compare_ints( const void* a, const void* b ) {

int* arg1 = (int*) a;

int* arg2 = (int*) b;

if( *arg1 < *arg2 ) return -1;

else if( *arg1 == *arg2 ) return 0;

else return 1;

}

int x[1000000];

int main(void)

{

int n,i,j,k;

while(scanf("%d%d",&n,&k))

{

if(n==0||k==0)

break;

for(i=0;i<n;i++)

scanf("%d",&x);

for(i=1;i<n;i++)if(x[i-1]>x)break;

if(i!=n)qsort( x, n, sizeof(int),compare_ints);

printf("%d\n",x[n-k]);

}

return 0;

}

其中紅字部分我有改過,

因為我本來想說會不會是有些測資是已經排序好的Sample,

用quicksort會特別慢。

後來我有把紅字改回來再試一次,

發現多了156ms

果然有差......

鏈接文章
分享到其他網站

我去查了一下中間鍵值的方法..

結果就AC了~xd

修改後的程式碼如下

#include <stdio.h>

#include <stdlib.h>

void sort(int x[],int left,int right)

{

int i,j,temp,k;

if(left<right)

{

i=left-1;

j=right+1;

k=x[(left+right)/2];

while(1)

{

while(x[++i]<k);

while(x[--j]>k);

if(i >= j)

break;

temp=x; x=x[j]; x[j]=temp;

}

sort(x,left,i-1);

sort(x,j+1,right);

}

}

int x[1000000];

int main(void)

{

int n,i,j,k;

while(scanf("%d%d",&n,&k)!=EOF)

{

if(n==0||k==0)

break;

for(i=0;i<n;i++)

scanf("%d",&x);

sort(x,0,n-1);

printf("%d\n",x[n-k]);

}

return 0;

}

速度是1484MS

的確快了很多喔

鏈接文章
分享到其他網站

其實如果真的是隨機的資料,

不管用哪裡當鍵值平均速度都是一樣的!!!

而且用了「除以」這項(奢侈的)運算其實會更花時間。

那你知道為什麼以第一個當鍵值會特別慢嗎?

因為設計測資的人知道,

大部分的人都會用第一個當鍵值,

所以就會故意放幾個(或很多個)幾近排序完成的測資,

這對以第一個當鍵值的quicksort是很傷的,

會造成n^2級的運算時間= =

其實不管用哪裡當鍵值,

都會有特別慢的情況出現,

只是用中間當鍵值會是比較保險的作法!!!

(不知道No1的265MS是怎麼做出來的= =

好可怕......)

鏈接文章
分享到其他網站
  • 2 months later...
  • 4 months later...
  • 2 weeks later...

請登入後來留意見

在登入之後,您才能留意見



立即登入