PAT DS 8-04 列印學生選課清單
阿新 • • 發佈:2018-12-31
這道題乍一看應該hash一下就可以了,沒想到做著做著發現,要麼時間不夠,要麼空間不夠……
1. 先確定用40111這個素數做hash表,儲存所有學生選課資訊。
2. 選了哪些課的儲存需要細細想想。題目沒給選課量的上限,先前根據實際情況考慮不會超過50門,遺憾的出現段錯誤。於是改用連結串列。
3. 題目沒說選課資訊會按照課程編號給出。所以還要對每個學生的選課連結串列做排序。我第一次用陣列儲存連結串列資訊下來,再做qsort,卻超時了。第二次改用,直接插入排序,AC了。由於某些原因,我的排序在輸出時做的,可以在處理選課資訊時(add函式裡)直接做。但應該從大端向小端掃描插入,需要用雙向連結串列和一個尾指標。
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h> #include <assert.h> #define HASH 40111 int n, k; typedef struct s_course{ int num; struct s_course *nx; }Cour; typedef struct s_student{ char na[5]; int cnt; Cour *co, *tail; struct s_student *nx; }Stud; Stud *st[HASH]; int hash(char *name); void add(char *name, int course); void printC(char *name); int main(void) { #ifdef DEBUG freopen("in.txt", "r", stdin); #endif scanf("%d%d", &n, &k); int i, j; for(i=0; i<k; ++i){ int c, s; scanf("%d%d", &c, &s); for(j=0; j<s; ++j){ char nm[5]; scanf("%s", nm); add(nm, c); } } // output for(i=0; i<n; ++i){ char nm[5]; scanf("%s", nm); printC(nm); } return 0; } int hash(char *name) { return (((name[0]-'A')<<14) + ((name[1]-'A')<<9) \ + ((name[2]-'A')<<4) + (name[3]-'0'))% HASH; } void add(char *na, int co) { int h = hash(na); Stud *ps = st[h], *pre = st[h]; while(ps != NULL){ pre = ps; if(strcmp(na, ps->na) == 0){ Cour *pc, *pct, *prec; pc = (Cour*)malloc(sizeof(Cour)); pc->num = co; pc->nx = ps->co; ps->co = pc; ++ps->cnt; return ; } ps = ps->nx; } // new if((ps = (Stud*)malloc(sizeof(Stud))) == NULL) exit(1); strcpy(ps->na, na); ps->co = (Cour*)malloc(sizeof(Cour)); ps->co->num = co; ps->co->nx = NULL; ++ps->cnt; if(pre != NULL) pre->nx = ps; else st[h] = ps; } void printC(char *na) { int h = hash(na); Stud *ps = st[h]; int co[2501], cnt=0; int i; while(ps != NULL){ if(strcmp(na, ps->na) == 0){ printf("%s %d", ps->na, ps->cnt); Cour *pc = ps->co; cnt = ps->cnt; co[cnt] = 2501; while(pc != NULL){ --cnt; for(i=cnt; i<ps->cnt; ++i){ if(co[i+1] > pc->num){ co[i] = pc->num; break; } else co[i] = co[i+1]; } #ifdef DEBUG printf("\n%d:", cnt); for(i=cnt; i<ps->cnt; ++i) printf("-%d", co[i]); #endif pc = pc->nx; } for(i=0; i<ps->cnt; ++i) printf(" %d", co[i]); printf("\n"); break; } ps = ps->nx; } if(ps == NULL) printf("%s 0\n", na); }