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 */

 

posted @ 2016-06-20 15:45  梁遇城  阅读(320)  评论(2)    收藏  举报