1055 The World's Richest (25 分)
题意
给出\(N\)个人的姓名、年龄及其拥有的财富值,然后进行K次查询。每次查询要求输出年龄范围在[AgeL, AgeR]的财富值从大到小的前M人的信息。如果财富值相同,则年龄小的优先;如果年龄也相同,则姓名的字典序小的优先。
暴力代码,水了\(22pts\)。
const int N=1e5+10;
struct Node
{
string name;
int age;
int worth;
bool operator<(const Node &W) const
{
if(worth != W.worth) return worth > W.worth;
if(age != W.age) return age < W.age;
return name < W.name;
}
}a[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i].name>>a[i].age>>a[i].worth;
int kase=1;
while(m--)
{
int k,l,r;
cin>>k>>l>>r;
vector<Node> v;
for(int i=0;i<n;i++)
if(a[i].age >= l && a[i].age <= r)
v.pb(a[i]);
cout<<"Case #"<<kase++<<':'<<endl;
if(v.size() == 0) cout<<"None"<<endl;
else
{
sort(v.begin(),v.end());
for(int i=0;i<k && i<v.size();i++)
cout<<v[i].name<<' '<<v[i].age<<' '<<v[i].worth<<endl;
}
}
//system("pause");
return 0;
}
一巧妙的做法,时间复杂度:\(O(nm)\),量级在\(10^7\),可以过。
const int N=1e5+10;
struct Node
{
string name;
int age;
int worth;
bool operator<(const Node &W) const
{
if(worth != W.worth) return worth > W.worth;
if(age != W.age) return age < W.age;
return name < W.name;
}
}a[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
a[i].name.resize(8);
scanf("%s %d %d",&a[i].name[0],&a[i].age,&a[i].worth);
}
sort(a,a+n);
int kase=1;
while(m--)
{
int k,l,r;
cin>>k>>l>>r;
printf("Case #%d:\n",kase++);
int cnt=0;
for(int i=0;cnt<k && i<n;i++)
if(a[i].age >= l && a[i].age <= r)
{
printf("%s %d %d\n",a[i].name.c_str(),a[i].age,a[i].worth);
cnt++;
}
if(cnt == 0) puts("None");
}
//system("pause");
return 0;
}
晴神的做法:
注意到\(M\)的范围仅在100以内,因此可以进行预处理,即将每个年龄中财富在前100名以内的人全都存到另一个数组中(因为某个年龄中财富值在100名以外的人永远不会被输出),后面查询的操作均在这个新数组中进行。这个预处理操作将显著降低查询的复杂度,时间复杂度:\(O(200*100*m)\),量级在\(2 \times 10^6\)。
const int N=1e5+10;
struct Node
{
string name;
int age;
int worth;
bool operator<(const Node &W) const
{
if(worth != W.worth) return worth > W.worth;
if(age != W.age) return age < W.age;
return name < W.name;
}
}a[N],b[N];
int book[210];
int tot;
int n,m;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
a[i].name.resize(8);
scanf("%s %d %d",&a[i].name[0],&a[i].age,&a[i].worth);
}
sort(a,a+n);
for(int i=0;i<n;i++)
if(book[a[i].age] < 100)
{
b[tot++]=a[i];
book[a[i].age]++;
}
int kase=1;
while(m--)
{
int k,l,r;
cin>>k>>l>>r;
printf("Case #%d:\n",kase++);
int cnt=0;
for(int i=0;i<tot;i++)
if(b[i].age >= l && b[i].age <= r)
{
printf("%s %d %d\n",b[i].name.c_str(),b[i].age,b[i].worth);
cnt++;
if(cnt == k) break;
}
if(cnt == 0) puts("None");
}
//system("pause");
return 0;
}