码迷,mamicode.com
首页 > 其他好文 > 详细

PAT Judge

时间:2017-05-24 20:20:06      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:create   nes   node   base   程序   each   lis   分享   contain   

本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》
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^410?4??), the total number of users, KKK (≤5\le 55), the total number of problems, and MMM (≤105\le 10^510?5??), 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-1?1 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 10000
 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 } userArr[MAX_USER];
 59 
 60 typedef struct node1 *ptrToSet;
 61 typedef struct node1 {
 62     /*
 63      * A array of node to store the user‘s datas
 64      */
 65     userArr arr;
 66     /*
 67      * A integer to implement table sort
 68      */
 69     int table[MAX_USER];
 70     /*
 71      * A integer array record the whole scores of the questions
 72      */
 73     int question[MAX_QUESTION];
 74 };
 75 
 76 /*
 77  *Create empty set of users and initialize the
 78  *solution all to -2 standing for question no submit
 79  *@param n The quantity of the users
 80  *@param m The quantity of the question
 81  */
 82 ptrToSet createEmptySet(int n, int k) {
 83     ptrToSet set = (ptrToSet) malloc(sizeof(struct node1));
 84     int i, j;
 85     for (i = 0; i < n; i++) {
 86         set->table[i] = i;
 87         for (j = 0; j < k; j++) {
 88             set->arr[i].solution[j] = -2;
 89             set->arr[i].perfectCouner = 0;
 90             set->arr[i].id = i;
 91         }
 92     }
 93     return set;
 94 }
 95 
 96 /*
 97  * Insert question total scores into set
 98  * @param set A point to point the set of users
 99  * @param m The quantity of the question
100  *
101  */
102 void insertQuestionScore(ptrToSet set, int k) {
103     int score, i;
104     for (i = 0; i < k; i++) {
105         scanf("%d", &score);
106         set->question[i] = score;
107     }
108 }
109 
110 /*
111  * Insert user‘s submit to set
112  * If the score is not than before,don‘t update,otherwise update it
113  * If the score is -1,update it into 0.
114  * If current score is equal question whole score,<code>perfectCounter</code>
115  * increase
116  * @param set A point to point the set
117  * @param m The quantity of the submit
118 
119  */
120 void insertUser(ptrToSet set, int m) {
121     /*
122      * @param The id of user,it is a positive integer number
123      * @param The id of question,it is a positive integer number
124      * @param score The score this submit geting
125      */
126     int id, qId, score, i;
127     for (i = 0; i < m; i++) {
128         scanf("%d %d %d", &id, &qId, &score);
129         /*
130          * Because the index in array begin from zreo
131          * In order to be compatible
132          */
133         id--;
134         qId--;
135         if (score < 0) {
136             score = 0;
137         }
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 = 0;
164         for (j = 0; j < k; j++) {
165             scorce = set->arr[i].solution[j];
166             if (scorce < 0) {
167                 scorce = 0;
168             }
169             totalScore += scorce;
170         }
171         set->arr[i].totalScore = totalScore;
172     }
173 }
174 
175 typedef struct node2 *ptrToNode;
176 typedef struct node2 {
177     /*
178      * Store the id of the user
179      */
180     int key;
181 
182     /*
183      * A point to point next node
184      */
185     ptrToNode next;
186 
187 };
188 
189 /*
190  * Define a data structure for bucket head that
191  * store the head point and rear point for the elements
192  */
193 typedef struct headNode {
194     ptrToNode head, rear;
195 };
196 
197 /*
198  * Define a array of headNode to store the all buckets
199  */
200 typedef struct headNode bucket[BUCKET_RADIX_TOTALSCORE];
201 
202 /*
203  * radix sort by perfect times in set.The perfect
204  * buckets is from 0 to <code>MAX_QUESTION</code>
205  * We sort uses according to perfect times DESC
206  * @param set A point to point the set
207  * @param n The quantity of users
208  */
209 void radixSortByPerfectTimes(ptrToSet set, int n) {
210     int di, i;
211     ptrToNode temp, list;
212     bucket b;
213     /*
214      * Initialize each bucket head and rear into NULL
215      */
216     for (i = 0; i < BUCKET_RADIX_PERFECT; i++) {
217         b[i].rear = b[i].head = NULL;
218     }
219     for (i = 0; i < n; i++) {
220         di = set->arr[i].perfectCouner;
221         temp = (ptrToNode) malloc(sizeof(struct node2));
222         temp->key = set->arr[i].id;
223         temp->next = NULL;
224         if (b[di].head == NULL) {
225             b[di].head = b[di].rear = temp;
226         } else {
227             b[di].rear->next = temp;
228             b[di].rear = temp;
229         }
230     }
231 
232     /*
233      * Recover the elements has been deal with,using
234      * the list to point the head
235      */
236     list = NULL;
237     for (i = 0; i < BUCKET_RADIX_PERFECT; i++) {
238         if (b[i].head) {
239             b[i].rear->next = list;
240             list = b[i].head;
241         }
242         b[i].head = b[i].rear = NULL;
243     }
244 
245     /*
246      * Set sorted sequence to table
247      */
248     for (i = 0; i < n; i++) {
249         temp = list;
250         list = list->next;
251         set->table[i] = temp->key;
252         free(temp);
253     }
254 }
255 
256 /*
257  * Get the digit by the current number and current needed digit
258  * @param x The current number
259  * @param d The current digit
260  * @return The digit needed
261  */
262 int getDigit(int x, int d) {
263     int i;
264     int di;
265     for (i = 0; i < d; i++) {
266         di = x % BUCKET_RADIX_TOTALSCORE;
267         x = x / BUCKET_RADIX_TOTALSCORE;
268     }
269     return di;
270 }
271 
272 /*
273  * Radix sort by total score
274  * @param set A point to point the set
275  * @param n The quantity of users
276  */
277 void radixSortByTotalScore(ptrToSet set, int n) {
278     int di, d, i, j;
279     ptrToNode temp, list;
280     bucket b;
281     /*
282      * Initialize each bucket head and rear into NULL
283      */
284     for (i = 0; i < BUCKET_RADIX_TOTALSCORE; i++) {
285         b[i].rear = b[i].head = NULL;
286     }
287     for (d = 1; d <= MAX_DIGIT; d++) {
288         for (j = 0; j < n; j++) {
289             di = getDigit(set->arr[set->table[j]].totalScore, d);
290             temp = (ptrToNode) malloc(sizeof(struct node2));
291             temp->key = set->table[j];
292             temp->next = NULL;
293             if (b[di].head == NULL) {
294                 b[di].head = b[di].rear = temp;
295             } else {
296                 b[di].rear->next = temp;
297                 b[di].rear = temp;
298             }
299         }
300 
301         /*
302          * Recover the elements has been deal with,using
303          * the list to point the head
304          */
305         list = NULL;
306         for (i = 0; i < BUCKET_RADIX_TOTALSCORE; i++) {
307             if (b[i].head) {
308                 b[i].rear->next = list;
309                 list = b[i].head;
310             }
311             b[i].head = b[i].rear = NULL;
312         }
313 
314         /*
315          * Set sorted sequence to table
316          */
317         for (i = 0; i < n; i++) {
318             temp = list;
319             list = list->next;
320             set->table[i] = temp->key;
321             free(temp);
322         }
323 
324     }
325 }
326 
327 /*
328  * Calculate the rank
329  */
330 void calculateRank(ptrToSet set, int n) {
331     int rank = 1;
332     int totalScore = set->arr[set->table[0]].totalScore;
333     int i;
334     set->arr[set->table[0]].rank = rank;
335     for (i = 1; i < n; i++) {
336         if (set->arr[set->table[i]].totalScore == totalScore) {
337             set->arr[set->table[i]].rank = rank;
338         } else {
339             rank = i + 1;
340             totalScore = set->arr[set->table[i]].totalScore;
341             set->arr[set->table[i]].rank = rank;
342         }
343     }
344 }
345 
346 /*
347  * Print the content of the set->table[i]
348  */
349 void toStingTable(ptrToSet set, int n) {
350     int i;
351     printf("table:");
352     for (i = 0; i < n; i++) {
353         printf("%d ", set->table[i]);
354     }
355 }
356 
357 /*
358  * Get the digit of a number to print format
359  */
360 int getDiditumber(int num) {
361     int counter = 0;
362     while (num != 0) {
363         num = num / 10;
364         counter++;
365     }
366     return counter;
367 }
368 
369 /*
370  * Print data to console
371  */
372 void toString(ptrToSet set, int n, int k) {
373     int i, j;
374     int digit;
375     for (i = 0; i < n; i++) {
376         if (set->arr[set->table[i]].totalScore == 0) {
377             continue;
378         }
379         printf("%d ", set->arr[set->table[i]].rank);
380         digit = getDiditumber(set->arr[set->table[i]].id + 1);
381         for (j = 0; j < (MAX_USER_DIGIT - digit); j++) {
382             printf("0");
383         }
384         printf("%d ", set->arr[set->table[i]].id + 1);
385         printf("%d ", set->arr[set->table[i]].totalScore);
386         for (j = 0; j < k; j++) {
387             if (set->arr[set->table[i]].solution[j] < 0) {
388                 printf("-");
389             } else {
390                 printf("%d", set->arr[set->table[i]].solution[j]);
391             }
392             if (j == k - 1) {
393 
394             } else {
395 
396                 printf(" ");
397             }
398         }
399         printf("\n");
400     }
401 }
402 
403 int main() {
404     int n, k, m;
405     scanf("%d %d %d", &n, &k, &m);
406     ptrToSet set = createEmptySet(MAX_USER, k);
407     insertQuestionScore(set, k);
408     insertUser(set, m);
409     n = MAX_USER;
410     toString(set, n, k);
411     calculateTotalSource(set, n, k);
412     radixSortByPerfectTimes(set, n);
413     radixSortByTotalScore(set, n);
414     calculateRank(set, n);
415     toString(set, n, k);
416     return 0;
417 }
Judge

代码还有两个点没有通过,但是我尽力了,上面的测试数据通过了

技术分享

PAT Judge

标签:create   nes   node   base   程序   each   lis   分享   contain   

原文地址:http://www.cnblogs.com/yghjava/p/6900653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!