标签:
摘自算法《竞赛入门经典训练指南》
例题 年龄排序(Age Sort,UVa 11462)
给定若干居民的年龄(都是1~100之间的整数),把它们按照从小到大的顺序输出。
【输入】
输入包含多组测试用例。每组数据的第一行为整数n(0<n<=2 000 000),即居民总数;下一行包含n个不小于1、不大于100的整数,即各居民的年龄。输入结束标志为n=0。
输入文件约有25mb,而内存限制只有2mb。
【输出】
对于每组数据,按照从小到大的顺序输出各居民的年龄,相邻年龄用单个空格隔开。
【分析】
由于数据太大,内存限制吃紧(甚至都不能把它们全读入内存),因此无法使用快速排序方法。但整数范围很小,可以用计数排序方法。下面是程序代码。
#include <cstdio>
#include <cstring>
int main(){
int n,x,c[101];
while(scanf("%d",&n)==1 && n){
memset(c,0,sizeof(c));
for(int i=0;i<n;i++){
scanf("%d",&x);
c[x]++;
}
int first=1;
for(int i=1;i<=100;i++){
for(int j=0;j<c[i];++j){
if(!first)printf(" ");
first=0;
printf("%d",i );
}
}
printf("\n");
}
}
如果还要精益求精,可以优化输入输出,进一步降低运行时间。程序如下。
#include <cstdio>
#include <cstring>
#include <cctype>
inline int readint(){
char c=getchar();
while(!isdigit(c))c=getchar();
int x=0;
while(isdigit(c)){
x=x*10+c-‘0‘;
c=getchar();
}
return x;//Warning: x > 0;
}
int buf[10];
inline void writeint(int i){
int p=0;
if(i==0)p++;
else while(i){
buf[p++]=i%10;
i/=10;
}
for(int j=p-1;j>=0;j--)putchar(‘0‘+buf[j]);//逆序输出
}
int main(){
int n,x,c[101];
while(n=readint()){
memset(c,0,sizeof c);
for(int i=0;i<n;++i)c[readint()]++;
int first=1;
for(int i=0;i<=100;++i){
for(int j=0;j<c[i];++j){
if(!first)putchar(‘ ‘);
first=0;
writeint(i);
}
}
putchar(‘\n‘);
}
return 0;
}
上述优化使得程序运行时间缩短了约2/3。一般情况下,当输入输出数据量很大时,应尽量用scanf和printf函数;如果时间效率还不够高,应逐字符输入输出,就像上面的readint和writeint函数。不管怎样,在确信I/O时间成为整个程序性能瓶颈之前,不要盲目优化。测试方法也很简单:输入之后不执行主算法,直接输出一个任意的结果,看运行时间是否过长。
标签:
原文地址:http://www.cnblogs.com/bruce27/p/4695184.html