pat1055

这题也是浙大今年上机题,而我作为练过大半年的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;
}


你可能感兴趣的:(优化,排序)