排序
A1025
问题:
思路:
关键:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N,K;
const int maxn = 30010;
struct stu{
char id[15];
int score,final_rank,local_number,local_rank;
};
stu a[maxn];
bool cmp(stu a,stu b){
if(a.score!=b.score) return a.score>b.score;
else return strcmp(a.id,b.id)<0;
}
int num = 0;
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%d",&K);
for(int j=0;j<K;j++){
scanf("%s %d",a[num].id,&a[num].score);
a[num].local_number = i;
num++;
}
sort(a+num-K,a+num,cmp);
a[num-K].local_rank = 1;
for(int j=1;j<K;j++){
if(a[num-K+j].score==a[num-K+j-1].score)
a[num-K+j].local_rank = a[num-K+j-1].local_rank;
else{
a[num-K+j].local_rank = j+1;
}
}
}
sort(a,a+num,cmp);
a[0].final_rank = 1;
for(int j=1;j<num;j++){
if(a[j].score==a[j-1].score)
a[j].final_rank = a[j-1].final_rank;
else{
a[j].final_rank = j+1;
}
}
printf("%d\n",num);
for(int i=0;i<num;i++){
printf("%s %d %d %d\n",a[i].id,a[i].final_rank,a[i].local_number,a[i].local_rank);
}
return 0;
}
A1062
问题:
思路:对于圣人、君子等可以在结构体中用一个level来区分
关键:
1.注意题目给出的范围,比如 10 5 {10}^5 105后面5个0 !
#include<cstdio>
#include<algorithm>
using namespace std;
int N,L,H,M=0;
struct people{
int id,v,t;
int total;
int level;
};
people a[100010];
bool cmp(people a,people b){
if(a.level!=b.level)
return a.level>b.level;
else{
if(a.total!=b.total)
return a.total>b.total;
else{
if(a.v!=b.v)
return a.v>b.v;
else{
return a.id < b.id;
}
}
}
}
int main(){
scanf("%d %d %d",&N,&L,&H);
int num = 0;
for(int i=0,id,v,t;i<N;i++){
scanf("%d %d %d",&id,&v,&t);
if(v>=L&&t>=L){
a[num].id = id;
a[num].v = v;
a[num].t = t;
a[num].total = v + t;
if(v>=H&&t>=H)
a[num].level = 4;
else if(v>=H&&t<H)
a[num].level = 3;
else if(v<=H&&t<=H&&v>=t)
a[num].level = 2;
else
a[num].level = 1;
num++;
}
}
sort(a,a+num,cmp);
printf("%d\n",num);
for(int i=0;i<num;i++){
printf("%d %d %d\n",a[i].id,a[i].v,a[i].t);
}
}
A1012【review | 主要看这里默认的一些规则】
默认规则:
对于分数相同的排名应该是 1 1 3 4 5,而不是1 1 2 3 4
平均分是四舍五入的,所以需要按照+0.5后取整,保证是四舍五入
ac代码:
#include<iostream>
#include<map>
#include<algorithm>
#include<set>
using namespace std;
const int maxn = 2010;
struct stu{
string id;
int g;
};
int N,M;
stu a[4][maxn];
bool cmp(stu x, stu y){
return x.g > y.g;
}
map<string,bool> book;
char lesson[4] = {
'A','C','M','E'};
int main(){
string str;
cin >> N >> M;
for(int i=0;i<N;i++){
cin >> str;
book[str]=true;
double sum = 0;
for(int j=1;j<=3;j++){
a[j][i].id = str;
cin >> a[j][i].g;
sum += a[j][i].g;
}
a[0][i].id = str;
//考虑四舍五入
a[0][i].g = (int)(sum/3+0.5);
}
for(int i=0;i<4;i++){
sort(a[i],a[i]+N,cmp);
}
for(int i=0;i<M;i++){
cin >> str;
if(!book[str]){
printf("N/A\n");
continue;
}
int best_rank = N+1;
int best_lesson = 0;
for(int j=0;j<4;j++){
int rank = 1;
for(int k=0;k<N;k++){
//还要考虑排名并列的情况
//是 1 1 3 4 5这种,而不是1 1 2 3 4
if(k!=0&&a[j][k].g!=a[j][k-1].g)
rank = k+1;
if(a[j][k].id==str&&best_rank>rank){
best_rank = rank;
best_lesson = j;
break;
}
}
}
printf("%d ",best_rank);
printf("%c\n",lesson[best_lesson]);
}
return 0;
}
A1016【好麻烦 有空做】
A1028
问题:
思路:写三个cmp
关键:
1.注意排序方向
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N,C;
struct node{
int id;
char name[10];
int score;
};
node a[100010];
bool cmp1(node a,node b){
return a.id < b.id;
}
bool cmp2(node a,node b){
if(strcmp(a.name,b.name)!=0)
return strcmp(a.name,b.name)<0;
else{
return a.id<b.id;
}
}
bool cmp3(node a,node b){
if(a.score!=b.score)
return a.score<b.score;
else{
return a.id<b.id;
}
}
int main(){
scanf("%d %d",&N,&C);
for(int i=0;i<N;i++){
scanf("%d %s %d",&a[i].id,a[i].name,&a[i].score);
}
if(C==1){
sort(a,a+N,cmp1);
}else if(C==2){
sort(a,a+N,cmp2);
}else{
sort(a,a+N,cmp3);
}
for(int i=0;i<N;i++){
printf("%06d %s %d\n",a[i].id,a[i].name,a[i].score);
}
}
A1055
问题:
思路:
关键:
1.如果采用对每个查询都时重新按年龄排一次序,或者在每次查询时都进行一次数组的复制,都会导致超时。
int a[] = {
'a','b','c'};
int b[10];
copy(a,a+3,b);//将a[0]~a[2]从b[0]开始复制给b
2.首先对整个数组进行排序,然后每次查询对源数组以age为条件遍历一遍的方式,能ac
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int N,K;
struct people{
char name[10];
int age,w;
};
people a[100010];
bool cmp(people a,people b){
return a.age<b.age;
}
bool cmp1(people a,people b){
if(a.w!=b.w){
return a.w>b.w;
}else{
if(a.age!=b.age){
return a.age<b.age;
}else{
return strcmp(a.name,b.name)<0;
}
}
}
int main(){
// freopen("1.txt","r",stdin);
scanf("%d %d",&N,&K);
for(int i=0;i<N;i++){
scanf("%s %d %d",a[i].name,&a[i].age,&a[i].w);
}
sort(a,a+N,cmp1);
int topK,L,H;
for(int i=1;i<=K;i++){
int printNum=0;
printf("Case #%d:\n",i);
scanf("%d %d %d",&topK,&L,&H);
for(int j=0;j<N&&printNum<topK;j++){
if(a[j].age>=L&&a[j].age<=H){
printf("%s %d %d\n",a[j].name,a[j].age,a[j].w);
printNum++;
}
}
if(printNum==0)printf("None\n");
}
}
3.考虑到查询数不超过100,因此可以取每个年龄段的前100人(后100人显然没有机会,反证法)组成一个规模较小的数组用来查询。能ac且效率更高。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int N,K;
struct people{
char name[10];
int age,w;
};
people a[100010];
people b[100010];
int bNum=0;
int age[210]={
0};
bool cmp(people a,people b){
return a.age<b.age;
}
bool cmp1(people a,people b){
if(a.w!=b.w){
return a.w>b.w;
}else{
if(a