传送门https://pintia.cn/problem-sets/1136515446447235072/problems/1136531088437108736
这道题真的出得跟shi一样
说好的顺序给出,但只要信了就会WA两个点(手动微笑
题目本身不难
把名字hash一下,然后用vector再排个序就ojbk了,甚至可以用优先队列
可是
大后天的数据结构机考不让用C++,只能用C
这是逼着让人手写链表排序啊woc
写就写吧 反正又不是没写过 上次写链表排序好像debug到凌晨两三点呜呜呜
然后就:
真爽
bug1:没有注意头指针为空
bug2:sort排序没有更新头指针的值
这就暴露出对递推的理解还是不够深,而且,太依赖C++的库函数了呜呜呜不让用C++的库函数可太惨了
唉 直接贴C的代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXN 180000
typedef struct Hash{
int val;
struct Hash *next;
}Hash;
Hash *hash[MAXN];
int to_num(char *s){//将名字hash成数字 最大hash(zzz9) = 175759
int sum = 0;
for(int i = 0; i < 3; ++i) sum = sum * 26 + s[i] - 'A';
sum = sum * 10 + s[3] - '0';
return sum;
}
void push(int id, int x){
if(hash[id] == NULL){//一定要注意最开始头指针为空
hash[id] = (Hash *)malloc(sizeof(Hash));
hash[id]->next = NULL;
hash[id]->val = x;
return;
}
Hash *p = hash[id];
while(p->next != NULL) p = p->next;
p->next = (Hash *)malloc(sizeof(Hash));
p->next->next = NULL;
p->next->val = x;
}
int size(Hash *p){//链表长度
int cnt = 0;
while(p != NULL){
p = p->next;
cnt++;
}
return cnt;
}
//链表的冒泡排序
Hash *bubble(Hash *p){
if(p->next != NULL && p->next->next != NULL) p->next = bubble(p->next);//递推冒泡,从尾端开始
if(p->val > p->next->val){//swap
Hash *str = p->next;
p->next = str->next;
str->next = p;
return str;
}
return p;
}
Hash *sort(Hash *p){
if(p != NULL && p->next != NULL){
p = bubble(p);//用冒泡将最小值冒到p位置,并更新p!!!
p -> next = sort(p->next);//然后递推下一个位置,并更新p->next!!!
}
return p;
}
void print(char *name, int id){
Hash *p = hash[id];
printf("%s %d", name, size(p));
p = sort(p);//sort后原来p不一定在头部,所以一定要更新p
while(p != NULL){
printf(" %d", p->val);
p = p->next;
}
printf("\n");
}
int main(){
int n, k, t, id, c;
char name[10];
scanf("%d%d", &n, &k);
memset(hash, (0, NULL), sizeof(Hash));
for(int i = 1; i <= k; i++){
scanf("%d%d", &c, &t);//虽然题目说的是顺序给出课程1~K是选课学生名单,但你要信了就WA了
while(t--){
scanf("%s", name);
id = to_num(name);//将学生名字hash成id
push(id, c);//将课程加入学生链表
}
}
scanf("%d", &n);
while(n--){
scanf("%s", &name);
id = to_num(name);
print(name, id);
}
return 0;
}