您的位置:首页 > 其它

NOIP 2011 普及组 复赛 swiss 瑞士轮

2017-03-27 10:52 465 查看
NOIP 2011 普及组 复赛 swiss 瑞士轮

1.对第一轮顺序心存疑惑,反复读题,结合样例明白了,还是按:第1 名和第2 名、第 3 名和第 4名、……、第2K – 1 名和第 2K名、…… 、第2N – 1 名和第2N名,各进行一场比赛。

2.因1 ≤ N ≤ 100,000,快速排序不可避免。

3.总分相同的,约定编号较小的选手排名靠前。两个快速排序函数必须。

4.采用结构体,思维负担比较小。

5.没注意到,选手数是2*N,以为是N个选手,提交测试点7TLE,测试点8、9、10RE,马上修改,提交,测试点7、8、9、10全TLE。

6.查了查,说是要用归并排序,那么一定要掌握归并排序的时候到了。

7.弄明白了归并排序的思想,以空间换时间。写好代码,提交10分,一查,一处笔误int i,j,k,ai=1,bi=1;//笔误,此处写成bi=2查了会 ,此处笔误提交10分

8.修改,提交AC。

附上AC代码,编译环境Dev-C++4.9.9.2

#include <stdio.h>

struct node{

    int i;//序号

    int f;//分数

    int w;//实力

}p[200000+100],a[200000+100],b[200000+20],p_t;//此处p[100000+100]提交错了后四个测试点。

int n;

void quicksort1(int left,int right){//f自大到小排序

    int i=left,j=right;

    int mid=p[(i+j)/2].f;

    while(i<=j){

        while(p[i].f>mid)

            i++;

        while(p[j].f<mid)

            j--;

        if(i<=j){

            p_t=p[i];

            p[i]=p[j];

            p[j]=p_t;

            i++;

            j--;

        }

    }

    if(left<j)

        quicksort1(left,j);

    if(i<right)

        quicksort1(i,right);

}

void quicksort2(int left,int right){//i自小到大排序

    int i=left,j=right;

    int mid=p[(i+j)/2].i;

    while(i<=j){

        while(p[i].i<mid)

            i++;

        while(p[j].i>mid)

            j--;

        if(i<=j){

            p_t=p[i];

            p[i]=p[j];

            p[j]=p_t;

            i++;

            j--;

        }

    }

    if(left<j)

        quicksort2(left,j);

    if(i<right)

        quicksort2(i,right);

}

void mergesort(){

    int i,j,k,ai=1,bi=1;//笔误,此处写成bi=2查了会 ,此处笔误提交10分

    for(i=1;i<=2*n-1;i+=2)

        if(p[i].w>p[i+1].w){

            p[i].f+=1;

            a[ai++]=p[i];//赢

            b[bi++]=p[i+1];//输

        }else{

            p[i+1].f+=1;

            a[ai++]=p[i+1];//赢

            b[bi++]=p[i];//输

        }

//归并排序

    i=1;

    j=1;

    k=1;

    while(i<ai&&j<bi)

        if(a[i].f>b[j].f)

            p[k++]=a[i++];

        else if(a[i].f<b[j].f)

            p[k++]=b[j++];

        else if(a[i].f==b[j].f)

            if(a[i].i<b[j].i)

                p[k++]=a[i++];

            else

                p[k++]=b[j++];

    while(i<ai)

        p[k++]=a[i++];

    while(j<bi)

        p[k++]=b[j++];

}

int main(){

    int r,q;

    int i,j,k;

    scanf("%d%d%d",&n,&r,&q);

    for(i=1;i<=2*n;i++){

        p[i].i=i;

        scanf("%d",&p[i].f);

    }

    for(i=1;i<=2*n;i++)

        scanf("%d",&p[i].w);

    //第一次排序,采用快速排序    

    quicksort1(1,2*n);

    j=1;

    while(j<=2*n){//同分,按序号由小到大排序

        k=1;

        while(j+1<=2*n&&p[j].f==p[j+1].f){

            j++;

            k++;

        }

        if(k>1)

            quicksort2(j-k+1,j);

        j++;

    }

    

    //r轮,采用归并排序思想排序

    for(i=1;i<=r;i++){//r轮

        mergesort();

    }

    printf("%d\n",p[q].i);

    return 0;

}

2017-3-28
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: