1. 程式人生 > >PAT DS 8-04 列印學生選課清單

PAT DS 8-04 列印學生選課清單

這道題乍一看應該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);
}