基本算法(1):排序

排序

这一类题还比较多,所以单独拿出来总结。
 
1012 The Best Rank (25 分)
 

To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algrbra), and E - English. At the mean time, we encourage students by emphasizing on their best ranks -- that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.

For example, The grades of CME and A - Average of 4 students are given as the following:

StudentID  C  M  E  A
310101     98 85 88 90
310102     70 95 88 84
310103     82 87 94 88
310104     91 91 91 91

Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (≤), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of CM and E. Then there are M lines, each containing a student ID.

Output Specification:

For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.

The priorities of the ranking methods are ordered as A C M E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.

If a student is not on the grading list, simply output N/A.

Sample Input:

5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999

Sample Output:

1 C
1 M
1 E
1 A
3 A
N/A
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m;
char name[4]={'A','C','M','E'};
struct st
{
    bool flag;
    int va[4];
    int r[4];
}inf[1000000];
struct ran
{
    int id;
    int value;
}cpg[2010],math[2010],eng[2010],avg[2010];
bool cmp(ran a,ran b)
{
    return a.value>b.value;
}
void deal(ran r[],int index)
{
    sort(r,r+n,cmp);
    for(int i=0;i<n;i++)
    {
        if(i>0&&r[i].value==r[i-1].value) inf[r[i].id].r[index]=inf[r[i-1].id].r[index];
        else inf[r[i].id].r[index]=i+1;
    }
}
void print(int id)
{
    if(inf[id].flag!=true)
    {
        printf("N/A\n");return;
    }
    int minr=2010,index;
    for(int i=0;i<4;i++)
    {
        if(inf[id].r[i]<minr)
        {
            minr=inf[id].r[i];
            index=i;
        }
        
    }
    printf("%d %c\n",minr,name[index]);
}
int main()
{
    scanf("%d%d",&n,&m);
    int id;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&id);
        inf[id].flag=true;
        scanf("%d%d%d",&inf[id].va[1],&inf[id].va[2],&inf[id].va[3]);
        inf[id].va[0]=inf[id].va[1]+inf[id].va[2]+inf[id].va[3];
    
        avg[i].id=id;avg[i].value=inf[id].va[0];
        cpg[i].id=id;cpg[i].value=inf[id].va[1];
        math[i].id=id;math[i].value=inf[id].va[2];
        eng[i].id=id;eng[i].value=inf[id].va[3];
    
    }
    //处理数据 
    deal(avg,0);
    deal(cpg,1);
    deal(math,2);
    deal(eng,3);
    //输出 
    for(int i=0;i<m;i++)
    {
        scanf("%d",&id);
        print(id);
    }

    return 0;
}

好琐碎,一点点理清思路就好了。

1016 Phone Bills (25 分)
 

A long-distance telephone company charges its customers by the following rules:

Making a long-distance call costs a certain amount per minute, depending on the time of day when the call is made. When a customer starts connecting a long-distance call, the time will be recorded, and so will be the time when the customer hangs up the phone. Every calendar month, a bill is sent to the customer for each minute called (at a rate determined by the time of day). Your job is to prepare the bills for each month, given a set of phone call records.

Input Specification:

Each input file contains one test case. Each case has two parts: the rate structure, and the phone call records.

The rate structure consists of a line with 24 non-negative integers denoting the toll (cents/minute) from 00:00 - 01:00, the toll from 01:00 - 02:00, and so on for each hour in the day.

The next line contains a positive number N (≤), followed by N lines of records. Each phone call record consists of the name of the customer (string of up to 20 characters without space), the time and date (mm:dd:hh:mm), and the word on-line or off-line.

For each test case, all dates will be within a single month. Each on-line record is paired with the chronologically next record for the same customer provided it is an off-line record. Any on-line records that are not paired with an off-line record are ignored, as are off-line records not paired with an on-line record. It is guaranteed that at least one call is well paired in the input. You may assume that no two records for the same customer have the same time. Times are recorded using a 24-hour clock.

Output Specification:

For each test case, you must print a phone bill for each customer.

Bills must be printed in alphabetical order of customers' names. For each customer, first print in a line the name of the customer and the month of the bill in the format shown by the sample. Then for each time period of a call, print in one line the beginning and ending time and date (dd:hh:mm), the lasting time (in minute) and the charge of the call. The calls must be listed in chronological order. Finally, print the total charge for the month in the format shown by the sample.

Sample Input:

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
10
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYJJ 01:01:07:00 off-line
CYLL 01:01:08:03 off-line
CYJJ 01:01:05:59 on-line
aaa 01:01:01:03 on-line
aaa 01:02:00:01 on-line
CYLL 01:28:15:41 on-line
aaa 01:05:02:24 on-line
aaa 01:04:23:59 off-line

Sample Output:

CYJJ 01
01:05:59 01:07:00 61 $12.10
Total amount: $12.10
CYLL 01
01:06:01 01:08:03 122 $24.40
28:15:41 28:16:05 24 $3.85
Total amount: $28.25
aaa 01
02:00:01 04:23:59 4318 $638.80
Total amount: $638.80


#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int n;
int rate[24];

struct record
{
    string name;
    int month,day,hour,min;
    bool judge;
}rs[1010];
bool cmp(record a,record b)
{
    if(a.name!=b.name) return a.name<b.name;
    else if(a.month!=b.month) return a.month<b.month;
    else if(a.day!=b.day) return a.day<b.day;
    else if(a.hour!=b.hour) return a.hour<b.hour;
    else if(a.min!=b.min) return a.min<b.min;
}
double calcu(record a,record b)
{
    int min_on=a.day*1440+b.hour*60+a.min;
    int min_off=b.day*1440+b.hour*60+b.min;
    int d_on=min_on/1440,d_off=min_off/1440;
    double sum=0;
    if(d_on==d_off)
    {
        if(a.hour==b.hour) sum+=rate[a.hour]*(b.min-a.min);
        else 
        {
            for(int j=a.hour;j<=b.hour;j++)
            {
                if(j==a.hour) sum+=(60-a.min)*rate[j];
                else if(j==b.hour) sum+=b.min*rate[j];
                else sum+=60*rate[j];
            }
        }
        return sum/100;
    }
    for(int i=d_on;i<=d_off;i++)
    {
        if(i==d_on) 
        {
            for(int j=a.hour;j<24;j++)
            {
                if(j==a.hour) sum+=(60-a.min)*rate[j];
                else sum+=60*rate[j];
            }
        }
        else if(i==d_off)
        {
            for(int j=0;j<=b.hour;j++)
            {
                if(j==b.hour) sum+=b.min*rate[j];
                else sum+=60*rate[j];
            }
        }
        else
        {
            for(int j=0;j<24;j++) sum+=60*rate[j];
        }
    }
    return sum/100;
}
int main()
{
    string name,judge;
    int month,day,hour,min;
    for(int i=0;i<24;i++) scanf("%d",&rate[i]);
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        cin>>name;
        scanf("%d:%d:%d:%d",&month,&day,&hour,&min);
        cin>>judge;
        rs[i].name=name;rs[i].month=month;rs[i].day=day;rs[i].hour=hour;rs[i].min=min;
        if(judge=="on-line") rs[i].judge=true;else rs[i].judge=false;
    }
    sort(rs,rs+n,cmp);//按姓名和时间排序
    string now="";
    
    for(int i=0;i<n;i++)
    {
        bool flag=false;
        
        if(now!=rs[i].name) 
        {
            now=rs[i].name;
            flag=false;     
        }
        for(i;i<n-1;i++)
        {
            if(rs[i+1].name!=now)
            {
                break;
            }else if(rs[i].judge==true&&rs[i+1].judge==false)
            {
                flag=true;
                break;
            } 
        }
        if(flag)
        {
            cout<<now;
            printf(" %02d\n",rs[i].month);
            double sum=0;
            for(i;i<n-1;i++)
            {
                if(rs[i+1].name==now&&rs[i].judge==true&&rs[i+1].judge==false)
                {
                    int last=rs[i+1].day*1440+rs[i+1].hour*60+rs[i+1].min-rs[i].day*1440-rs[i].hour*60-rs[i].min;
                    double t=calcu(rs[i],rs[i+1]);
                    sum+=t;
                    printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",rs[i].day,rs[i].hour,rs[i].min,
                    rs[i+1].day,rs[i+1].hour,rs[i+1].min,last,t);                        
                }
                if(rs[i+1].name!=now) break;
            }
            printf("Total amount: $%.2f\n",sum);
        }
        
    }
    return 0;
}

这一题可要疯了,最初用复杂映射向量和结构体,想要直接一步到位算出结果直接查询,最后搞乱了。然后改为现求现打印结果。虽然各个细节的实现没那么难,想好后就容易入手了。

主要遇到的难点在:储存记录并判断有效的一对记录,记录排序,求通话时间和费用(要考虑是否同一天同一小时),输出时还不能输出没有有效记录的用户(题目打脸!),以及具体实现时遇到的小问题。

1025 PAT Ranking (25 分)
 

Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your job to write a program to correctly merge all the ranklists and generate the final rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive number N (≤), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (≤), the number of testees, and then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:

registration_number final_rank location_number local_rank

The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.

Sample Input:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

Sample Output:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct record
{
    char id[15];
    int local;
    int score;
    int lrank;
}inf[30010];
bool cmp(record a,record b)
{
    if(a.score!=b.score) return a.score>b.score;
    else return strcmp(a.id,b.id)<0; 
}

int main()
{
    int n,k;
    scanf("%d",&n);
    int index=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&k);
        for(int j=0;j<k;j++)
        {
            scanf("%s %d",inf[index].id,&inf[index].score);
            inf[index].local=i;
            index++;
        }
        sort(inf+index-k,inf+index,cmp);
        
        inf[index-k].lrank=1;
        for(int j=index-k+1;j<index;j++)
        {
            if(inf[j].score==inf[j-1].score) inf[j].lrank=inf[j-1].lrank;
            else
            {
                inf[j].lrank=j+1-index+k;
            }
        }
    }
    sort(inf,inf+index,cmp);
    printf("%d\n",index);
    int rank=1;
    printf("%s 1 %d %d\n",inf[0].id,inf[0].local,inf[0].lrank);
    for(int i=1;i<index;i++)
    {
        printf("%s ",inf[i].id);
        if(inf[i].score==inf[i-1].score) printf("%d",rank);
        else
        {
            printf("%d",i+1);rank=i+1;
        }
        printf(" %d %d\n",inf[i].local,inf[i].lrank); 
    } 
    return 0;
}
1028 List Sorting (25 分)
 

Excel can sort records according to any column. Now you are supposed to imitate this function.

Input Specification:

Each input file contains one test case. For each case, the first line contains two integers N (≤) and C, where N is the number of records and C is the column that you are supposed to sort the records with. Then N lines follow, each contains a record of a student. A student's record consists of his or her distinct ID (a 6-digit number), name (a string with no more than 8 characters without space), and grade (an integer between 0 and 100, inclusive).

Output Specification:

For each test case, output the sorting result in N lines. That is, if C = 1 then the records must be sorted in increasing order according to ID's; if C = 2 then the records must be sorted in non-decreasing order according to names; and if C = 3 then the records must be sorted in non-decreasing order according to grades. If there are several students who have the same name or grade, they must be sorted according to their ID's in increasing order.

.。。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct st
{
    int id;
    char name[10];
    int grade;
}inf[100010];
bool cmp1(st a,st b)
{
    return a.id<b.id;
}
bool cmp2(st a,st b)
{
    if(strcmp(a.name,b.name)!=0) return strcmp(a.name,b.name)<0;
    else return a.id<b.id;
}
bool cmp3(st a,st b)
{
    if(a.grade!=b.grade) return a.grade<b.grade;
    else return a.id<b.id;
    
}
int main()
{
    int n,c;
    scanf("%d %d",&n,&c);
    for(int i=0;i<n;i++)
    {
        scanf("%d %s %d",&inf[i].id,inf[i].name,&inf[i].grade);
    }
    switch (c){
        case 1:sort(inf,inf+n,cmp1);break;
        case 2:sort(inf,inf+n,cmp2);break;
        case 3:sort(inf,inf+n,cmp3);break;
    }    
    for(int i=0;i<n;i++)
    {
        printf("%06d %s %d\n",inf[i].id,inf[i].name,inf[i].grade);
    }    
    return 0;
}

本来应该简单,但是一些细节使得结果不对,比如名字数组大小过小等。用string就好了。写3个sort比较函数。

 

1055 The World's Richest (25 分)
 

Forbes magazine publishes every year its list of billionaires based on the annual ranking of the world's wealthiest people. Now you are supposed to simulate this job, but concentrate only on the people in a certain range of ages. That is, given the net worths of N people, you must find the M richest people in a given range of their ages.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤) - the total number of people, and K (≤) - the number of queries. Then N lines follow, each contains the name (string of no more than 8 characters without space), age (integer in (0, 200]), and the net worth (integer in [−]) of a person. Finally there are K lines of queries, each contains three positive integers: M (≤) - the maximum number of outputs, and [AminAmax] which are the range of ages. All the numbers in a line are separated by a space.

Output Specification:

For each query, first print in a line Case #X: where X is the query number starting from 1. Then output the Mrichest people with their ages in the range [AminAmax]. Each person's information occupies a line, in the format

Name Age Net_Worth

The outputs must be in non-increasing order of the net worths. In case there are equal worths, it must be in non-decreasing order of the ages. If both worths and ages are the same, then the output must be in non-decreasing alphabetical order of the names. It is guaranteed that there is no two persons share all the same of the three pieces of information. In case no one is found, output None.

Sample Input:

12 4
Zoe_Bill 35 2333
Bob_Volk 24 5888
Anny_Cin 95 999999
Williams 30 -22
Cindy 76 76000
Alice 18 88888
Joe_Mike 32 3222
Michael 5 300000
Rosemary 40 5888
Dobby 24 5888
Billy 24 5888
Nobody 5 0
4 15 45
4 30 35
4 5 95
1 45 50

Sample Output:

Case #1:
Alice 18 88888
Billy 24 5888
Bob_Volk 24 5888
Dobby 24 5888
Case #2:
Joe_Mike 32 3222
Zoe_Bill 35 2333
Williams 30 -22
Case #3:
Anny_Cin 95 999999
Michael 5 300000
Alice 18 88888
Cindy 76 76000
Case #4:
None

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,k;
int age[210]={0};
struct inf
{
    char name[10];
    int age;
    int wea;
}all[100010],valid[100010];
bool cmp(inf a,inf b)
{
    if(a.wea!=b.wea) return a.wea>b.wea;
    else if(a.age!=b.age) return a.age<b.age;
    else return strcmp(a.name,b.name)<0;
}

int main()
{
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%s %d %d",all[i].name,&all[i].age,&all[i].wea);
        
    }
    sort(all,all+n,cmp);
    int num=0;
    for(int i=0;i<n;i++)
    {
        if(age[all[i].age]<100)
        {
            age[all[i].age]++;
            valid[num++]=all[i];
        }
    }
    int m,x,y;
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d%d",&m,&x,&y);
        printf("Case #%d:\n",i);
        int sum=0;
        for(int j=0;j<num&&sum<m;j++)
        {
            if(valid[j].age>=x&&valid[j].age<=y)
            {
                printf("%s %d %d\n",valid[j].name,valid[j].age,valid[j].wea);
                sum++;
            }
        }
        if(sum==0) printf("None\n");
    }
    return 0;
}

这一类题大概就是sort排序原始数据,但为了不超时需要进行预处理,这便是难点所在,否则只能得一半分左右。而进行预处理的技巧也不是很好把握。只能靠积累了。

这一题先根据题意,输出满足年龄的前M个,M不超过100,那么就每一个年龄最多只能输出100个,这样就清楚了:遍历一次总的数据,将每个年龄的前100个都留下来

放在另一个数组里,同时用数组记录并实时更新各年龄的人数,不能超过100;最后查询时在新的数据数组里查。

1075 PAT Judge (25 分)
 

The ranklist of PAT is generated from the status list, which shows the scores of the submissions. This time you are supposed to generate the ranklist for PAT.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 positive integers, N (≤), the total number of users, K (≤), the total number of problems, and M (≤), the total number of submissions. It is then assumed that the user id's are 5-digit numbers from 00001 to N, and the problem id's are from 1 to K. The next line contains K positive integers p[i] (i=1, ..., K), where p[i] corresponds to the full mark of the i-th problem. Then M lines follow, each gives the information of a submission in the following format:

user_id problem_id partial_score_obtained

where partial_score_obtained is either − if the submission cannot even pass the compiler, or is an integer in the range [0, p[problem_id]]. All the numbers in a line are separated by a space.

Output Specification:

For each test case, you are supposed to output the ranklist in the following format:

rank user_id total_score s[1] ... s[K]

where rank is calculated according to the total_score, and all the users with the same total_score obtain the same rank; and s[i] is the partial score obtained for the i-th problem. If a user has never submitted a solution for a problem, then "-" must be printed at the corresponding position. If a user has submitted several solutions to solve one problem, then the highest score will be counted.

The ranklist must be printed in non-decreasing order of the ranks. For those who have the same rank, users must be sorted in nonincreasing order according to the number of perfectly solved problems. And if there is still a tie, then they must be printed in increasing order of their id's. For those who has never submitted any solution that can pass the compiler, or has never submitted any solution, they must NOT be shown on the ranklist. It is guaranteed that at least one user can be shown on the ranklist.

Sample Input:

7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0

Sample Output:

1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -

#include <cstdio>
#include <algorithm>
using namespace std;
int n,k,m;
int p[6];

struct user
{
    int id;
    int s[6];
    int sum,vs;
    bool f;
}data[10010]; 
void init()
{
    for(int i=1;i<=n;i++)
    {
        data[i].id=i;
        data[i].sum=0;
        data[i].vs=0;
        data[i].f=false;
        fill(data[i].s,data[i].s+6,-1);
    }
}
bool cmp(user a,user b)
{
    if(a.sum!=b.sum) return a.sum>b.sum;
    else if(a.vs!=b.vs) return a.vs>b.vs;
    else return a.id<b.id;
}
int main()
{
    int id,score,pos,num=0;
    scanf("%d %d %d",&n,&k,&m);
    init();
    for(int i=1;i<=k;i++) scanf("%d",&p[i]);
    for(int i=0;i<m;i++)
    {
        scanf("%d %d %d",&id,&pos,&score);
        if(score>=0) data[id].f=true;
        data[id].id=id;
        if(data[id].s[pos]==-1&&score==-1) data[id].s[pos]=0;
        if(score==p[pos]&&data[id].s[pos]<p[pos]) data[id].vs++;
        if(score>data[id].s[pos]) data[id].s[pos]=score;
        
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            if(data[i].s[j]!=-1) data[i].sum+=data[i].s[j];
        }
    }
    sort(data+1,data+n+1,cmp);
    int rank=1;
    for(int i=1;i<=n;i++)
    {
        if(data[i].f==false) continue;
        if(i>1&&data[i].sum!=data[i-1].sum) rank=i;
        printf("%d %05d %d",rank,data[i].id,data[i].sum);
        for(int j=1;j<=k;j++)
        {
            if(data[i].s[j]==-1) printf(" -");
            else printf(" %d",data[i].s[j]);
        }
        printf("\n");
    }
    return 0;
}

太菜了我。思路没什么错,但是莫名其妙一个点不对。也许就差在算法规范或者是细节上。粗糙的解法轻易得一半以上分,但离满分差在哪里呢?

1080 Graduate Admission (30 分)
 

It is said that in 2011, there are about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.

Each applicant will have to provide two grades: the national entrance exam grade GE​​, and the interview grade GI​​. The final grade of an applicant is (. The admission rules are:

  • The applicants are ranked according to their final grades, and will be admitted one by one from the top of the rank list.

  • If there is a tied final grade, the applicants will be ranked according to their national entrance exam grade GE​​. If still tied, their ranks must be the same.

  • Each applicant may have K choices and the admission will be done according to his/her choices: if according to the rank list, it is one's turn to be admitted; and if the quota of one's most preferred shcool is not exceeded, then one will be admitted to this school, or one's other choices will be considered one by one in order. If one gets rejected by all of preferred schools, then this unfortunate applicant will be rejected.

  • If there is a tied rank, and if the corresponding applicants are applying to the same school, then that school must admit all the applicants with the same rank, even if its quota will be exceeded.

Input Specification:

Each input file contains one test case.

Each case starts with a line containing three positive integers: N (≤), the total number of applicants; M (≤), the total number of graduate schools; and K (≤), the number of choices an applicant may have.

In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.

Then N lines follow, each contains 2 integers separated by a space. The first 2 integers are the applicant's GE​​ and GI​​, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M1, and the applicants are numbered from 0 to N1.

Output Specification:

For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants' numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.

Sample Input:

11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4

Sample Output:

0 10
3
5 6 7
2 8

1 4

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN=40010;
int n,m,k;
struct st
{
    int id,rank;
    int ge,gi;
    int sum;
    int pref[6];
}inf[MAXN];

struct u
{
    int quota;
    int sum;
    int sid[MAXN];
    int last;
}sc[100]; 
bool cmp(st a,st b)
{
    if(a.sum!=b.sum) return a.sum>b.sum;
    else return a.ge>b.ge;
}
bool cmpp(int a,int b)
{
    return inf[a].id<inf[b].id;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<m;i++)
    {
        scanf("%d",&sc[i].quota);
        sc[i].sum=0;
        sc[i].last=-1;
    }
    
    for(int i=0;i<n;i++)
    {
        inf[i].id=i;
        scanf("%d%d",&inf[i].ge,&inf[i].gi);
        inf[i].sum=inf[i].ge+inf[i].gi;
        for(int j=0;j<k;j++) scanf("%d",&inf[i].pref[j]);
    }
    sort(inf,inf+n,cmp);
    int r=1;inf[0].rank=r;
    for(int i=1;i<n;i++)
    {
        if(inf[i].sum==inf[i-1].sum&&inf[i].ge==inf[i-1].ge) inf[i].rank=inf[i-1].rank;
        else
        {
            r++;inf[i].rank=r;
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<k;j++)
        {
            int school=inf[i].pref[j];
            int num=sc[school].sum;
            if(num<sc[school].quota||(sc[school].last!=-1&&inf[i].rank==inf[ sc[school].last ].rank))
            {
                sc[school].sid[num]=i;
                sc[school].last=i;
                sc[school].sum++;
                break;
            }
        }
    }
    for(int i=0;i<m;i++)
    {
        sort(sc[i].sid,sc[i].sid+sc[i].sum,cmpp);
        int l=sc[i].sum;        
        for(int j=0;j<l;j++)
        {
            printf("%d",inf[sc[i].sid[j]].id);
            if(j<l-1) printf(" ");
        
        }
        printf("\n");
    }
    return 0;
}

最初的方法只得了26分,本以为是因为用向量数组存学校录取,会出现问题,但改为了用结构体还是一样的结果。用书上的方法,差别在其排序前,先把真正编号存下,之后的操作里

学生的编号都是用排序后的号。然后在输出时再代回去找原编号。还是不明白为什么这样就对了。关键在没过的那2个点,但暂时无从得知。

猜你喜欢

转载自www.cnblogs.com/fremontxutheultimate/p/11396130.html
今日推荐