PAT Judge

本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》
10-排序5 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, NNN (≤104\le 10^4104​​), the total number of users, KKK (≤5\le 55), the total number of problems, and MMM (≤105\le 10^5105​​), the total number of submissions. It is then assumed that the user id's are 5-digit numbers from 00001 to NNN, and the problem id's are from 1 to KKK. The next line contains KKK positive integers p[i] (i=1, ..., KKK), where p[i] corresponds to the full mark of the i-th problem. Then MMM 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 −1-11 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 -
  • 时间限制:200ms
  • 内存限制:64MB
  • 代码长度限制:16kB
  • 判题程序:系统默认
  • 作者:陈越
  • 单位:浙江大学

 

算法思想:

Algorithms thoughts:
 *     Using bucket sort latest significant Digit
 *     1.sort id
 *     2.sort perfect solution
 *     3.sort total scores

 

下面是代码:

  1 /*
  2  * judge.c
  3  *
  4  *  Created on: 2017年5月24日
  5  *      Author: ygh
  6  * Algorithms thoughts:
  7  *     Using bucket sort latest significant Digit
  8  *     1.sort id
  9  *     2.sort perfect solution
 10  *     3.sort total scores
 11  */
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #define MAX_QUESTION 5
 15 #define MAX_USER_DIGIT 5
 16 #define MAX_USER 100000
 17 
 18 /*
 19  * The radix of the perfect times,it from 0 to MAX_QUESTION
 20  */
 21 #define BUCKET_RADIX_PERFECT 6
 22 
 23 /*
 24  * The radix of total score,the value if from 0 to 9
 25  */
 26 #define BUCKET_RADIX_TOTALSCORE 10
 27 /*
 28  * The score max digit
 29  */
 30 #define MAX_DIGIT 6
 31 
 32 typedef struct node {
 33     /*
 34      * The id of the user
 35      */
 36     int id;
 37     /*
 38      * A integer array to record the score of
 39      * each question
 40      */
 41     int solution[MAX_QUESTION];
 42 
 43     /*
 44      * The times about the prefer solution times
 45      */
 46     int perfectCouner;
 47 
 48     /*
 49      * The total score
 50      */
 51     int totalScore;
 52 
 53     /*
 54      * The rank of the user
 55      */
 56     int rank;
 57 
 58     int showFlag;
 59 
 60 } userArr[MAX_USER];
 61 
 62 typedef struct node1 *ptrToSet;
 63 typedef struct node1 {
 64     /*
 65      * A array of node to store the user's datas
 66      */
 67     userArr arr;
 68     /*
 69      * A integer to implement table sort
 70      */
 71     int table[MAX_USER];
 72     /*
 73      * A integer array record the whole scores of the questions
 74      */
 75     int question[MAX_QUESTION];
 76 };
 77 
 78 /*
 79  *Create empty set of users and initialize the
 80  *solution all to -2 standing for question no submit
 81  *@param n The quantity of the users
 82  *@param m The quantity of the question
 83  */
 84 ptrToSet createEmptySet(int n, int k) {
 85     ptrToSet set = (ptrToSet) malloc(sizeof(struct node1));
 86     int i, j;
 87     for (i = 0; i < n; i++) {
 88         set->table[i] = i;
 89         for (j = 0; j < k; j++) {
 90             set->arr[i].solution[j] = -2;
 91             set->arr[i].perfectCouner = 0;
 92             set->arr[i].id = i;
 93             set->arr[i].showFlag = 0;
 94         }
 95     }
 96     return set;
 97 }
 98 
 99 /*
100  * Insert question total scores into set
101  * @param set A point to point the set of users
102  * @param m The quantity of the question
103  *
104  */
105 void insertQuestionScore(ptrToSet set, int k) {
106     int score, i;
107     for (i = 0; i < k; i++) {
108         scanf("%d", &score);
109         set->question[i] = score;
110     }
111 }
112 
113 /*
114  * Insert user's submit to set
115  * If the score is not than before,don't update,otherwise update it
116  * If the score is -1,update it into 0.
117  * If current score is equal question whole score,<code>perfectCounter</code>
118  * increase
119  * @param set A point to point the set
120  * @param m The quantity of the submit
121 
122  */
123 void insertUser(ptrToSet set, int m) {
124     /*
125      * @param The id of user,it is a positive integer number
126      * @param The id of question,it is a positive integer number
127      * @param score The score this submit geting
128      */
129     int id, qId, score, i;
130     for (i = 0; i < m; i++) {
131         scanf("%d %d %d", &id, &qId, &score);
132         /*
133          * Because the index in array begin from zreo
134          * In order to be compatible
135          */
136         id--;
137         qId--;
138         if (set->arr[id].solution[qId] < score) {
139             set->arr[id].solution[qId] = score;
140             if (score == set->question[qId]) {
141                 set->arr[id].perfectCouner++;
142             }
143         }
144     }
145 
146 }
147 
148 /*
149  * Calculate the total score
150  * We don't decrease scores,if the score is negative number
151  * we let it to zero and add it.But we need the negative number as
152  * a flag when we print the submit result:
153  *         1.The use never submitted,print '-'
154  *         2.The user submit but don't pass compiler get zeor,but we need
155  *             print zero to console
156  *        3.If the total score is zero,we don't show them
157  */
158 void calculateTotalSource(ptrToSet set, int n, int k) {
159     int i, j;
160     int totalScore;
161     int scorce;
162     for (i = 0; i < n; i++) {
163         totalScore = -1;
164         for (j = 0; j < k; j++) {
165             scorce = set->arr[i].solution[j];
166             if (scorce < 0 && totalScore == -1) {
167                 totalScore = -1;
168             } else if (scorce == 0 && totalScore == -1) {
169                 totalScore = 0;
170             } else if (scorce > 0 && totalScore == -1) {
171                 totalScore = scorce;
172             } else if(scorce > 0) {
173                 totalScore += scorce;
174             }
175         }
176         set->arr[i].totalScore = totalScore;
177     }
178 }
179 
180 void calculateShowFlag(ptrToSet set, int n) {
181     int i;
182     for (i = 0; i < n; i++) {
183         if (set->arr[i].totalScore > -1) {
184             set->arr[i].showFlag = 1;
185         } else {
186             set->arr[i].showFlag = 0;
187             set->arr[i].totalScore = 0;
188         }
189     }
190 }
191 
192 typedef struct node2 *ptrToNode;
193 typedef struct node2 {
194     /*
195      * Store the id of the user
196      */
197     int key;
198 
199     /*
200      * A point to point next node
201      */
202     ptrToNode next;
203 
204 };
205 
206 /*
207  * Define a data structure for bucket head that
208  * store the head point and rear point for the elements
209  */
210 typedef struct headNode {
211     ptrToNode head, rear;
212 };
213 
214 /*
215  * Define a array of headNode to store the all buckets
216  */
217 typedef struct headNode bucket[BUCKET_RADIX_TOTALSCORE];
218 
219 /*
220  * radix sort by perfect times in set.The perfect
221  * buckets is from 0 to <code>MAX_QUESTION</code>
222  * We sort uses according to perfect times DESC
223  * @param set A point to point the set
224  * @param n The quantity of users
225  */
226 void radixSortByPerfectTimes(ptrToSet set, int n) {
227     int di, i;
228     ptrToNode temp, list;
229     bucket b;
230     /*
231      * Initialize each bucket head and rear into NULL
232      */
233     for (i = 0; i < BUCKET_RADIX_PERFECT; i++) {
234         b[i].rear = b[i].head = NULL;
235     }
236     for (i = 0; i < n; i++) {
237         di = set->arr[i].perfectCouner;
238         temp = (ptrToNode) malloc(sizeof(struct node2));
239         temp->key = set->arr[i].id;
240         temp->next = NULL;
241         if (b[di].head == NULL) {
242             b[di].head = b[di].rear = temp;
243         } else {
244             b[di].rear->next = temp;
245             b[di].rear = temp;
246         }
247     }
248 
249     /*
250      * Recover the elements has been deal with,using
251      * the list to point the head
252      */
253     list = NULL;
254     for (i = 0; i < BUCKET_RADIX_PERFECT; i++) {
255         if (b[i].head) {
256             b[i].rear->next = list;
257             list = b[i].head;
258         }
259         b[i].head = b[i].rear = NULL;
260     }
261 
262     /*
263      * Set sorted sequence to table
264      */
265     for (i = 0; i < n; i++) {
266         temp = list;
267         list = list->next;
268         set->table[i] = temp->key;
269         free(temp);
270     }
271 }
272 
273 /*
274  * Get the digit by the current number and current needed digit
275  * @param x The current number
276  * @param d The current digit
277  * @return The digit needed
278  */
279 int getDigit(int x, int d) {
280     int i;
281     int di;
282     for (i = 0; i < d; i++) {
283         di = x % BUCKET_RADIX_TOTALSCORE;
284         x = x / BUCKET_RADIX_TOTALSCORE;
285     }
286     return di;
287 }
288 
289 /*
290  * Radix sort by total score
291  * @param set A point to point the set
292  * @param n The quantity of users
293  */
294 void radixSortByTotalScore(ptrToSet set, int n) {
295     int di, d, i, j;
296     ptrToNode temp, list;
297     bucket b;
298     /*
299      * Initialize each bucket head and rear into NULL
300      */
301     for (i = 0; i < BUCKET_RADIX_TOTALSCORE; i++) {
302         b[i].rear = b[i].head = NULL;
303     }
304     for (d = 1; d <= MAX_DIGIT; d++) {
305         for (j = 0; j < n; j++) {
306             di = getDigit(set->arr[set->table[j]].totalScore, d);
307             temp = (ptrToNode) malloc(sizeof(struct node2));
308             temp->key = set->table[j];
309             temp->next = NULL;
310             if (b[di].head == NULL) {
311                 b[di].head = b[di].rear = temp;
312             } else {
313                 b[di].rear->next = temp;
314                 b[di].rear = temp;
315             }
316         }
317 
318         /*
319          * Recover the elements has been deal with,using
320          * the list to point the head
321          */
322         list = NULL;
323         for (i = 0; i < BUCKET_RADIX_TOTALSCORE; i++) {
324             if (b[i].head) {
325                 b[i].rear->next = list;
326                 list = b[i].head;
327             }
328             b[i].head = b[i].rear = NULL;
329         }
330 
331         /*
332          * Set sorted sequence to table
333          */
334         for (i = 0; i < n; i++) {
335             temp = list;
336             list = list->next;
337             set->table[i] = temp->key;
338             free(temp);
339         }
340 
341     }
342 }
343 
344 /*
345  * Calculate the rank
346  */
347 void calculateRank(ptrToSet set, int n) {
348     int rank = 1;
349     int totalScore = set->arr[set->table[0]].totalScore;
350     int i;
351     set->arr[set->table[0]].rank = rank;
352     for (i = 1; i < n; i++) {
353         if (set->arr[set->table[i]].totalScore == totalScore) {
354             set->arr[set->table[i]].rank = rank;
355         } else {
356             rank = i + 1;
357             totalScore = set->arr[set->table[i]].totalScore;
358             set->arr[set->table[i]].rank = rank;
359         }
360     }
361 }
362 
363 /*
364  * Print the content of the set->table[i]
365  */
366 void toStingTable(ptrToSet set, int n) {
367     int i;
368     printf("table:");
369     for (i = 0; i < n; i++) {
370         printf("%d ", set->table[i]);
371     }
372 }
373 
374 /*
375  * Get the digit of a number to print format
376  */
377 int getDiditumber(int num) {
378     int counter = 0;
379     while (num != 0) {
380         num = num / 10;
381         counter++;
382     }
383     return counter;
384 }
385 
386 /*
387  * Print data to console
388  */
389 void toString(ptrToSet set, int n, int k) {
390     int i, j;
391     int digit;
392     for (i = 0; i < n; i++) {
393         if (set->arr[set->table[i]].showFlag == 0) {
394             continue;
395         }
396         printf("%d ", set->arr[set->table[i]].rank);
397         digit = getDiditumber(set->arr[set->table[i]].id + 1);
398         for (j = 0; j < (MAX_USER_DIGIT - digit); j++) {
399             printf("0");
400         }
401         printf("%d ", set->arr[set->table[i]].id + 1);
402         printf("%d ", set->arr[set->table[i]].totalScore);
403         for (j = 0; j < k; j++) {
404             if (set->arr[set->table[i]].solution[j] ==-2) {
405                 printf("-");
406             } else if(set->arr[set->table[i]].solution[j] ==-1){
407                 printf("0");
408             }else{
409                 printf("%d",set->arr[set->table[i]].solution[j]);
410             }
411             if (j == k - 1) {
412 
413             } else {
414 
415                 printf(" ");
416             }
417         }
418         printf("\n");
419     }
420 }
421 
422 int main() {
423     int n, k, m;
424     scanf("%d %d %d", &n, &k, &m);
425     ptrToSet set = createEmptySet(MAX_USER, k);
426     insertQuestionScore(set, k);
427     insertUser(set, m);
428     n = MAX_USER;
429 //    toString(set, n, k);
430     calculateTotalSource(set, n, k);
431     calculateShowFlag(set, n);
432     radixSortByPerfectTimes(set, n);
433     radixSortByTotalScore(set, n);
434     calculateRank(set, n);
435     toString(set, n, k);
436     return 0;
437 }
PTA Judge

The code pass all test points perfectly

 

posted @ 2017-05-24 19:41  浪漫逆风  阅读(772)  评论(0编辑  收藏  举报