PAT Judge
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^4≤104), the total number of users, KKK (≤5\le 5≤5), the total number of problems, and MMM (≤105\le 10^5≤105), 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 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 }
The code pass all test points perfectly