这题也是浙大今年上机题,而我作为练过大半年的acmer,还是在慌乱中没能拿到满分,今天的话,这题我做了40分钟大概,这题其实不难拿满分,只需要一点经验吧。总觉得某些时候我们忽略了一些条件,这题的话是这个年龄的范围,一般的方法是大家都想得到,能拿到21分,关于超时的那些数据,我只想说,查出来的最多有100个人,但是我得找100000个人,可见很多人其实不用找的,而且他是根据年龄是找的,那么有个想法就产生了,我记下每个年龄的第一次和最后一次出现的位置(是排完序后的位置),然后再他给我的范围年龄中,我枚举每一个年龄,找到他们中最早出现那个的最小值和最晚出现的最大值,作为我查找的范围,这样我就可以确保,我要找的人都在这些范围里,而且我把查找的范围缩小了很多。
代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;
#define N 100005
struct node
{
char n[30];
int ag,w;
}p[N];
int st[201];
int ed[201];
bool cmp(node a ,node b)
{
if(a.w==b.w)
{
if(a.ag==b.ag)
return strcmp(a.n,b.n)<0;
return a.ag<b.ag;
}
return a.w>b.w;
}
int main()
{
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%s%d%d",p[i].n,&p[i].ag,&p[i].w);
sort(p+1,p+n+1,cmp);
for(i=1;i<=200;i++)
{
st[i]=N;
ed[i]=0;
}
for(i=1;i<=n;i++)
{
if(st[p[i].ag]>i)
st[p[i].ag]=i;
if(ed[p[i].ag]<i)
ed[p[i].ag]=i;
}
int ca=0;
while(m--)
{
int num,x,y;
scanf("%d%d%d",&num,&x,&y);
printf("Case #%d:\n",++ca);
int cnt=0;
int min=10000000;
int max=-1;
for(i=x;i<=y;i++)
{
if(st[i]==N||ed[i]==0)
continue;
if(st[i]<min)
min=st[i];
if(ed[i]>max)
max=ed[i];
}
for(i=min;i<=max;i++)
{
if(p[i].ag>=x&&p[i].ag<=y)
{
printf("%s %d %d\n",p[i].n,p[i].ag,p[i].w);
cnt++;
if(cnt==num)
break;
}
}
if(cnt==0)
printf("None\n");
}
return 0;
}