PAT 1015 德才论
宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”
现给出一批考生的德才分数,请根据司马光的理论给出录取排名。
输入格式:
输入第1行给出3个正整数,分别为:N(<=105),即考生总数;L(>=60),为录取最低分数线,即德分和才分均不低于L的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线L的考生也按总分排序,但排在第三类考生之后。
随后N行,每行给出一位考生的信息,包括:准考证号、德分、才分,其中准考证号为8位整数,德才分为区间[0, 100]内的整数。数字间以空格分隔。
输出格式:
输出第1行首先给出达到最低分数线的考生人数M,随后M行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。
输入样例:
14 60 80 10000001 64 90 10000002 90 60 10000011 85 80 10000003 85 80 10000004 80 85 10000005 82 77 10000006 83 76 10000007 90 78 10000008 75 79 10000009 59 90 10000010 88 45 10000012 80 100 10000013 90 99 10000014 66 60
输出样例:
12 10000013 90 99 10000012 80 100 10000003 85 80 10000011 85 80 10000004 80 85 10000007 90 78 10000006 83 76 10000005 82 77 10000002 90 60 10000014 66 60 10000008 75 79 10000001 64 90
提交了几次,都部分正确,主要是运行超时,以下是超时代码:
1 /* 2 * main.c 3 * 4 * Created on: 2016年6月19日 5 * Author: Will 6 */ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 11 typedef struct listNode 12 { 13 unsigned long stuNum; 14 unsigned int markD; 15 unsigned int markC; 16 unsigned int sum; 17 struct listNode *nextPtr; 18 }ListNode; 19 20 typedef ListNode *ListNodePtr; 21 22 void insert(ListNodePtr *sPtr, ListNodePtr currentPtr); 23 void printList(ListNodePtr currentPtr); 24 25 int main(void) 26 { 27 ListNodePtr listAPtr = NULL; 28 ListNodePtr listBPtr = NULL; 29 ListNodePtr listCPtr = NULL; 30 ListNodePtr listDPtr = NULL; 31 ListNodePtr newPtr; 32 33 unsigned long totalNum = 0; 34 unsigned long passNum = 0; 35 unsigned int markH; 36 unsigned int markL; 37 38 unsigned long i; 39 40 scanf("%ld %d %d", &totalNum, &markL, &markH); 41 // printf("%ld %d %d\n", totalNum, markH, markL); 42 43 for(i = 0; i < totalNum; i++) 44 { 45 newPtr = malloc(sizeof(ListNode)); 46 47 if(newPtr) 48 { 49 scanf("%ld %d %d", &newPtr->stuNum, &newPtr->markD, &newPtr->markC); 50 newPtr->sum = newPtr->markD + newPtr->markC; 51 newPtr->nextPtr = NULL; 52 53 // printList(newPtr); 54 55 if(newPtr->markD >= markL && newPtr->markC >= markL) 56 { 57 passNum++; 58 59 if(newPtr->markD >= markH && newPtr->markC >= markH) 60 { 61 insert(&listAPtr, newPtr); 62 } 63 else if(newPtr->markD >= markH && newPtr->markC < markH) 64 { 65 insert(&listBPtr, newPtr); 66 } 67 else if(newPtr->markD >= newPtr->markC) 68 { 69 insert(&listCPtr, newPtr); 70 } 71 else 72 { 73 insert(&listDPtr, newPtr); 74 } 75 } 76 } 77 else 78 { 79 // printf("The memory is not enough.\n\n"); 80 } 81 } 82 83 printf("%ld\n", passNum); 84 printList(listAPtr); 85 printList(listBPtr); 86 printList(listCPtr); 87 printList(listDPtr); 88 89 return 0; 90 } 91 92 void insert(ListNodePtr *sPtr, ListNodePtr newPtr) 93 { 94 ListNodePtr previousPtr; 95 ListNodePtr currentPtr; 96 97 if(newPtr) 98 { 99 previousPtr = NULL; 100 currentPtr = *sPtr; 101 102 while(currentPtr != NULL && newPtr->sum <= currentPtr->sum) 103 { 104 if(newPtr->sum == currentPtr->sum) 105 { 106 if(newPtr->markD <= currentPtr->markD) 107 { 108 if(newPtr->markD == currentPtr->markD) 109 { 110 if(newPtr->stuNum > currentPtr->stuNum) 111 { 112 previousPtr = currentPtr; 113 currentPtr = currentPtr->nextPtr; 114 } 115 else 116 { 117 break; 118 } 119 } 120 else 121 { 122 previousPtr = currentPtr; 123 currentPtr = currentPtr->nextPtr; 124 } 125 } 126 else 127 { 128 break; 129 } 130 } 131 else 132 { 133 previousPtr = currentPtr; 134 currentPtr = currentPtr->nextPtr; 135 } 136 } 137 138 if(previousPtr == NULL) 139 { 140 newPtr->nextPtr = *sPtr; 141 *sPtr = newPtr; 142 } 143 else 144 { 145 previousPtr->nextPtr = newPtr; 146 newPtr->nextPtr = currentPtr; 147 } 148 } 149 else 150 { 151 // printf("The newPtr is empty.\n\n"); 152 } 153 } 154 155 void printList(ListNodePtr currentPtr) 156 { 157 if(!currentPtr) 158 { 159 // printf("The list is empty.\n\n"); 160 } 161 else 162 { 163 while(currentPtr) 164 { 165 printf("%ld %d %d\n", currentPtr->stuNum, \ 166 currentPtr->markD, currentPtr->markC); 167 currentPtr = currentPtr->nextPtr; 168 } 169 } 170 } 171 172 /* END OF FILE */
请大家看看有什么能改进的地方~
--------------------------------------------------------------------------------------
20160622
在网上搜了这道题的信息,大多是是C++写的,确切地说,我没找到谁用C写的版本。今天用结构体的方式重写了,先输入信息,分组,然后每组归并排序,第一次提交,前面4个用例都正确,最后一个显示段错误。将代码中的==替换为>=后,测试通过。下面为通过版本代码:
1 /* 2 * main.c 3 * 4 * Created on: 2016年6月22日 5 * Author: Will 6 */ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <stdbool.h> 11 12 typedef struct stuInfo 13 { 14 unsigned long stuNum; 15 unsigned int markD; 16 unsigned int markC; 17 unsigned int grade; 18 }stuInfo; 19 20 typedef stuInfo *stuInfoPtr; 21 22 inline bool compare(stuInfoPtr aPtr, stuInfoPtr bPtr) 23 { 24 if((aPtr->markD + aPtr->markC) != (bPtr->markD + bPtr->markC)) 25 return ((aPtr->markD + aPtr->markC) < (bPtr->markD + bPtr->markC)); 26 else 27 { 28 if(aPtr->markD != bPtr->markD) 29 { 30 return (aPtr->markD < bPtr->markD); 31 } 32 else 33 { 34 return (aPtr->stuNum > bPtr->stuNum); 35 } 36 } 37 } 38 39 void subArraySort(stuInfoPtr aPtr[], unsigned long low, unsigned long high); 40 void merge(stuInfoPtr aPtr[], unsigned long left, unsigned long middle1, \ 41 unsigned long middle2, unsigned long right); 42 void groupArray(stuInfoPtr aPtr[], unsigned long cnt); 43 void sortArray(stuInfoPtr aPtr[], unsigned long cnt); 44 void printArray(stuInfoPtr aPtr[], unsigned long cnt); 45 void printSubArray(stuInfoPtr aPtr[], unsigned long left, unsigned long right); 46 47 unsigned long gradeA = 0, gradeB = 0, gradeC = 0, gradeD = 0; 48 unsigned long passNum = 0; 49 50 int main(void) 51 { 52 unsigned long totalNum = 0; 53 unsigned int markL, markH; 54 unsigned long i; 55 unsigned long arrayIndex = 0; 56 57 stuInfoPtr newPtr; 58 stuInfoPtr *arrayPtr; 59 60 scanf("%ld %d %d", &totalNum, &markL, &markH); 61 62 if(totalNum > 100000) 63 totalNum = 100000; 64 65 arrayPtr = malloc(totalNum * sizeof(stuInfoPtr)); 66 67 for(i = 0; i < totalNum; i++) 68 { 69 newPtr = malloc(sizeof(stuInfo)); 70 71 if(newPtr) 72 { 73 scanf("%ld %d %d", &newPtr->stuNum, &newPtr->markD, &newPtr->markC); 74 75 if(newPtr->markD >= markL && newPtr->markC >= markL) 76 { 77 passNum++; 78 arrayPtr[arrayIndex++] = newPtr; 79 80 if(newPtr->markD >= markH && newPtr->markC >= markH) 81 { 82 newPtr->grade = 1; 83 gradeA++; 84 } 85 else if(newPtr->markD >= markH) 86 { 87 newPtr->grade = 2; 88 gradeB++; 89 } 90 else if(newPtr->markD >= newPtr->markC) 91 { 92 newPtr->grade = 3; 93 gradeC++; 94 } 95 else 96 { 97 newPtr->grade = 4; 98 gradeD++; 99 } 100 } 101 } 102 else 103 { 104 printf("The memory is not enough.\n"); 105 } 106 } 107 108 groupArray(arrayPtr, passNum); 109 sortArray(arrayPtr, passNum); 110 111 printf("%ld\n", passNum); 112 printArray(arrayPtr, passNum); 113 114 return 0; 115 } 116 117 void groupArray(stuInfoPtr aPtr[], unsigned long cnt) 118 { 119 unsigned long i; 120 unsigned long indexA = 0; 121 unsigned long indexB = gradeA; 122 unsigned long indexC = gradeA + gradeB; 123 124 stuInfoPtr tempPtr = NULL; 125 126 for(i = 0; i < cnt; i++) 127 { 128 if(aPtr[i]->grade == 1) 129 { 130 tempPtr = aPtr[indexA]; 131 aPtr[indexA++] = aPtr[i]; 132 aPtr[i] = tempPtr; 133 } 134 } 135 136 for(i = indexB; i < cnt; i++) 137 { 138 if(aPtr[i]->grade == 2) 139 { 140 tempPtr = aPtr[indexB]; 141 aPtr[indexB++] = aPtr[i]; 142 aPtr[i] = tempPtr; 143 } 144 } 145 146 for(i = indexC; i < cnt; i++) 147 { 148 if(aPtr[i]->grade == 3) 149 { 150 tempPtr = aPtr[indexC]; 151 aPtr[indexC++] = aPtr[i]; 152 aPtr[i] = tempPtr; 153 } 154 } 155 } 156 157 void sortArray(stuInfoPtr aPtr[], unsigned long cnt) 158 { 159 if(gradeA > 1) 160 { 161 subArraySort(aPtr, 0, gradeA - 1); 162 } 163 164 if(gradeB > 1) 165 { 166 subArraySort(aPtr, gradeA, gradeA + gradeB - 1); 167 } 168 169 if(gradeC > 1) 170 { 171 subArraySort(aPtr, gradeA + gradeB, gradeA + gradeB + gradeC - 1); 172 } 173 174 if(gradeD > 1) 175 { 176 subArraySort(aPtr, gradeA + gradeB + gradeC, cnt - 1); 177 } 178 } 179 180 void subArraySort(stuInfoPtr aPtr[], unsigned long low, unsigned long high) 181 { 182 unsigned long middle1, middle2; 183 184 if((high - low) >= 1) 185 { 186 middle1 = (high + low) / 2; 187 middle2 = middle1 + 1; 188 189 subArraySort(aPtr, low, middle1); 190 subArraySort(aPtr, middle2, high); 191 192 merge(aPtr, low, middle1, middle2, high); 193 } 194 } 195 196 void merge(stuInfoPtr aPtr[], unsigned long left, unsigned long middle1, \ 197 unsigned long middle2, unsigned long right) 198 { 199 unsigned long leftIndex = left; 200 unsigned long rightIndex = middle2; 201 unsigned long combinedIndex = left; 202 stuInfoPtr tempPtr[passNum]; 203 unsigned long i; 204 205 while(leftIndex <= middle1 && rightIndex <= right) 206 { 207 if(!compare(aPtr[leftIndex], aPtr[rightIndex])) 208 tempPtr[combinedIndex++] = aPtr[leftIndex++]; 209 else 210 tempPtr[combinedIndex++] = aPtr[rightIndex++]; 211 } 212 213 if(leftIndex >= middle2) 214 { 215 while(rightIndex <= right) 216 tempPtr[combinedIndex++] = aPtr[rightIndex++]; 217 } 218 else 219 { 220 while(leftIndex <= middle1) 221 tempPtr[combinedIndex++] = aPtr[leftIndex++]; 222 } 223 224 for(i = left; i <= right; i++) 225 aPtr[i] = tempPtr[i]; 226 } 227 228 void printArray(stuInfoPtr aPtr[], unsigned long cnt) 229 { 230 if(cnt >= 1) 231 printSubArray(aPtr, 0, cnt - 1); 232 } 233 234 void printSubArray(stuInfoPtr aPtr[], unsigned long left, unsigned long right) 235 { 236 unsigned long i; 237 238 for(i = left; i <= right; i++) 239 { 240 printf("%ld %d %d\n", aPtr[i]->stuNum, aPtr[i]->markD, aPtr[i]->markC); 241 } 242 } 243 /* END OF FILE */

浙公网安备 33010602011771号