POJ2371

POJ2371  问题与答案

首先给出一  个N,一下N行接着给N个数,然后是一个K,接着是K行查询,要问这N个数从小到大的第i个数是多少?

输入:1<=N<=100000,以后每个数1<=X<=5000;查询1<=K<=100,以后每个查询1<=Y<=N。

输出:按照每个查询一次输出第i个数。

分析:由于N有10万个如果用快排排序之后(花费O(nlogn)时间),然后对于每个查询用O(1)时间输出的话,总复杂度就是O(nlogn)。如果用计数排序(由于每个数最多是5000)在O(n)时间里读入并排好每个数,然后对于100个查询每个查询要扫描一遍5000规模的数组,则共最多50万次计算,而用快排要大于1000万次计算。

首先用快排看下程序速度多快:47MS,且用了564K的内存

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100000+100;
int n,a[maxn],k;
int main()
{
   scanf("%d",&n);
   for(int i=0;i<n;i++)
    {
       scanf("%d",&a[i]);
    }
   sort(a,a+n);
 
   char s[100];
   scanf("%s",s);
   //printf("%s\n",s);
   scanf("%d",&k);
   while(k--)
    {
       int x;
       scanf("%d",&x);
       printf("%d\n",a[x-1]);
    }
   return 0;
}
现在看下第二种计数排序方法多快:47MS,192K内存。第二种方法更优
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=5000+100;
int n,a[maxn],k;//a[x]==y,表示数值为X的这个数出现了y次
int main()
{
   scanf("%d",&n);
   memset(a,0,sizeof(a));
   for(int i=0;i<n;i++)
    {
        int x;scanf("%d",&x);
       a[x]++;
    }
   char s[100];
   scanf("%s",s);
   scanf("%d",&k);
   while(k--)
    {
       int x,cnt=0;
       scanf("%d",&x);
       for(int i=0;i<maxn;i++)
       {
           cnt+=a[i];
           if(cnt>=x)
           {
                printf("%d\n",i);
                break;
           }
       }
    }
   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值