NYOJ----776删除元素

删除元素

时间限制:1000 ms  |  内存限制:65535 KB

描述

题意很简单,给一个长度为n的序列,问至少删除序列中多少个数,使得删除后的序列中的最大值<= 2*最小值

输入

多组测试数据,每组测试数据包含两行。
第一行一个整数n( n <= 10^5),序列中元素的个数。
第二行依次输入n个数a1,a2……an,(1 <= ai <= 10^9)以空格分开。

输出

输出占一行,至少要删除数的个数。

样例输入

6

5 4 3 3 8 6

样例输出

1

思路:
先对n个数排序,然后从前往后删除元素Min,同时用二分求出原集合大于2*Min的数的个数,从而可以确定每轮满足题意而删除元素的个数,比较可得最小值,时间复杂度O(nlogn)
#include <stdio.h> 
#include <stdlib.h>
#define M 100000//是10^5次方 
struct test{
    int n,ans,*num,i,tmp,l,r;
    void init()
    {
        ans = M;
        num = (int *)malloc(sizeof(int)*(n));
        for(i=0;i<n;i++)
            scanf("%d",&num[i]);
    }
    int deletenum()
    {
        QuickSort(num,0,n-1);//升序
        for(i=0;i<n;i++) 
        {
            //binarysearch
            l = i,r = n;
            while(l<r)
            {
                tmp = (l+r)/2;
                if(num[tmp] > 2*num[i])
                    r = tmp;
                else{
                    l = tmp + 1; 
                }
            }
            if(n-r+i < ans)//是n-r+i且小于 
                ans = n-r+i;
        }
        return ans;
    }
    void QuickSort(int *num,int p,int r)
    {
        int q;
        if(p<r)
        {
            q = partition(num,p,r);
            QuickSort(num,p,q-1);//q-1
            QuickSort(num,q+1,r);
        }
    }
    int partition(int *num,int p,int r)
    {
        int i = p,j = r+1;
        int x = num[p];
        while(1)
        {
            while(num[++i] < x && i < r);//i < r
            while(num[--j] > x);
            if(i >= j) break;
            swap(num,i,j);
        }
        swap(num,p,j);
        return j;
    }
    void swap(int *num,int i,int j)
    {
        num[i] = num[j] + num[i] - (num[j] = num[i]);
    }
}test;
int main()
{
    while(~scanf("%d",&test.n))//多组测试数据 
    {
        test.init();
        printf("%d\n",test.deletenum());
    } 
    return 0;
} 

 参照:http://blog.csdn.net/lyhvoyage/article/details/12884653

posted @ 2016-03-23 23:17  我在这儿  阅读(275)  评论(0编辑  收藏  举报