PAT A1055 The Word's Richest 简单思路

本文分享了算法竞赛中一种高效的排序和搜索策略,通过对比预处理和直接搜索的方法,展示了如何在不显著增加时间复杂度的情况下,简化代码并提高效率。适合对算法优化感兴趣的读者。

题目链接
《算法笔记》里面的方法其实挺好的,作者说如果在输出之前不先预处理一下排序数据, 会在第二个测试点那里超时。 但事实上并不会超时, 可能是因为现在服务器运算速度比几年前高了?

书上的参考代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int age[10010]={0};
struct Per{
	char name[20];
	int age, worth;
}per[100010],valid[100010];
bool cmp(Per a, Per b){
	if (a.worth!=b.worth) return a.worth>b.worth;
	else if (a.age!=b.age) return a.age<b.age;
	else return strcmp(a.name,b.name)<0;
}
int main(){
	int n,k;
	scanf("%d %d",&n,&k);
	for (int i=0; i<n; i++){
		scanf("%s %d %d",per[i].name,&per[i].age, &per[i].worth);
	}
	sort(per,per+n,cmp);
	int validNum=0;
	for (int i=0; i<n; i++){
		if (age[per[i].age]<100){
			age[per[i].age]++;
			valid[validNum++]=per[i];
		}
	} 
	int m,ageL,ageR;
	for (int i=1; i<=k; i++){
		scanf("%d %d %d",&m,&ageL,&ageR);
		printf("Case #%d:\n",i);
		int printNum=0;
		for (int j=0; j<validNum && printNum<m; j++){
			if (valid[j].age>=ageL && valid[j].age<=ageR){
				printf("%s %d %d\n",valid[j].name, valid[j].age, valid[j].worth);
				printNum++;
			}
		}
		if (!printNum) {
			printf("None\n");
		}
	}
}

不进行预处理也能通过的代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Per{
	char name[20];
	int age, worth;
}per[100010];
bool cmp(Per a, Per b){
	if (a.worth!=b.worth) return a.worth>b.worth;
	else if (a.age!=b.age) return a.age<b.age;
	else return strcmp(a.name,b.name)<0;
}
int main(){
	int n,k;
	scanf("%d %d",&n,&k);
	for (int i=0; i<n; i++){
		scanf("%s %d %d",per[i].name,&per[i].age, &per[i].worth);
	}
	sort(per,per+n,cmp);
	for (int i=0; i<k; i++){
		int m,amin,amax;
		scanf("%d %d %d",&m,&amin,&amax);
		printf("Case #%d:\n",i+1);
		int count=0, j=0;
		while (count<m && j<n){
			if (per[j].age>=amin && per[j].age<=amax) {
				count++;
				printf("%s %d %d\n",per[j].name, per[j].age, per[j].worth);
			}
			j++;
		}
		if (!count) printf("None\n");
	}
}

不进行预处理,用时是进行预处理的两倍,但是思路呢,会简单很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值