diff --git a/semester3/pset6/7-1-朋友圈点赞.c b/semester3/pset6/7-1-朋友圈点赞.c new file mode 100644 index 0000000..89042a5 --- /dev/null +++ b/semester3/pset6/7-1-朋友圈点赞.c @@ -0,0 +1,59 @@ +#include +#define MAXLEN 256 +#define SIZE 5 + +int getDigits(int i) { + int count = 0; + do { + i /= 10; + count++; + } while (i); + + return count; +} + +int main(void) { + // remember to initialize to 0 + int matrix[SIZE][SIZE] = {}; + int liked[SIZE][SIZE] = {}; + + char buf[MAXLEN]; + fgets(buf, MAXLEN, stdin); + int offset = 0; + int src, dist; + + while (sscanf(buf + offset, "%d,%d,", &src, &dist) != EOF) { + // printf("%d -> %d\n", src, dist); + offset += getDigits(src) + getDigits(dist) + 2; + matrix[src][dist] = 1; + } + + // calculate likes + for (int i = 0; i < SIZE; i++) { + int count = 0; + for (int j = 0; j < SIZE; j++) { + if (matrix[i][j] == 1) { + if (++count % 2 == 1) { + // printf("%d liked %d, count: %d\n", i, j, count); + liked[i][j] = 1; + } + } + } + } + + scanf("%d", &dist); + + int hasLikes = 0; + for (int i = 0; i < SIZE; i++) { + if (liked[i][dist] == 1) { + hasLikes = 1; + printf("%d,", i); + } + } + + if (!hasLikes) { + printf("-1"); + } + + return 0; +} diff --git a/semester3/pset6/7-2-拓扑排序.c b/semester3/pset6/7-2-拓扑排序.c new file mode 100644 index 0000000..6ab1151 --- /dev/null +++ b/semester3/pset6/7-2-拓扑排序.c @@ -0,0 +1,184 @@ +// NEEDS REWORKING +#include +#include +#define SIZE 11 + +typedef struct listNode { + char ID; + struct listNode *next; +} listNode; + +typedef struct queue { + listNode **arr; + int back; + int front; +} queue; + +listNode *newNode(char ID) { + listNode *new = malloc(sizeof(listNode)); + new->ID = ID; + new->next = NULL; + + return new; +} + +queue *newQueue() { + queue *q = malloc(sizeof(queue)); + q->arr = malloc(sizeof(listNode *) * SIZE); + q->back = 0; + q->front = 0; + return q; +} + +void appendNode(listNode *node, listNode *new) { + while (node->next != NULL) { + node = node->next; + } + node->next = new; +} + +void push(listNode *li, queue *q) { q->arr[q->back++] = li; } + +int isEmpty(queue *q) { return (q->front == q->back); } + +listNode *getFront(queue *q) { return q->arr[q->front]; } + +void pop(queue *q) { + if (!isEmpty(q)) { + q->front++; + } +} + +listNode **makeGraph() { + + listNode **graph = malloc(sizeof(listNode *) * SIZE); + + // initialize graph + int count = 0; + graph[count++] = newNode('S'); + for (; count < 10; count++) { + graph[count] = newNode(count + 'A' - 1); + } + graph[count++] = newNode('T'); + + appendNode(graph[0], newNode('A')); + appendNode(graph[0], newNode('D')); + appendNode(graph[0], newNode('G')); + + appendNode(graph[1], newNode('B')); + appendNode(graph[1], newNode('E')); + + appendNode(graph[2], newNode('C')); + + appendNode(graph[3], newNode('T')); + + appendNode(graph[4], newNode('A')); + appendNode(graph[4], newNode('E')); + + appendNode(graph[5], newNode('C')); + appendNode(graph[5], newNode('F')); + appendNode(graph[5], newNode('I')); + + appendNode(graph[6], newNode('C')); + appendNode(graph[6], newNode('T')); + + appendNode(graph[7], newNode('D')); + appendNode(graph[7], newNode('E')); + appendNode(graph[7], newNode('H')); + + appendNode(graph[8], newNode('E')); + appendNode(graph[8], newNode('I')); + + appendNode(graph[9], newNode('F')); + appendNode(graph[9], newNode('T')); + + return graph; +} + +int ch2digit(char ch) { + if (ch == 'S') { + return 0; + } else if (ch == 'T') { + return 10; + } else { + return ch - 'A' + 1; + } +} + +int *getIndegree(listNode **g) { + int *inDegree = malloc(sizeof(int) * SIZE); + for (int i = 0; i < SIZE; i++) { // init to 0 + inDegree[i] = 0; + } + + for (int i = 0; i < SIZE; i++) { + listNode *ptr = g[i]->next; + while (ptr != NULL) { + inDegree[ch2digit(ptr->ID)]++; + ptr = ptr->next; + } + } + + // for (int i = 0; i < SIZE; i++) { + // printf("%c: %d\n", g[i]->ID, inDegree[i]); + // } + + return inDegree; +} + +void topoSort(listNode **g) { + queue *q = newQueue(); + int visited[SIZE] = {}; + int *inDegree = getIndegree(g); + + for (int count = 0; count < SIZE; count++) { + + for (int i = 0; i < SIZE; i++) { + if (inDegree[i] == 0 && visited[i] == 0) { + // printf("pushing: %c\n", g[i]->ID); + push(g[i], q); + visited[i] = 1; + } + } + + listNode *tmp; + while (!isEmpty(q)) { + tmp = getFront(q); + pop(q); + printf("%c,", tmp->ID); + + tmp = g[ch2digit(tmp->ID)]->next; + while (tmp != NULL) { + if (--inDegree[ch2digit(tmp->ID)] == 0 && + visited[ch2digit(tmp->ID)] == 0) { + push(tmp, q); + visited[ch2digit(tmp->ID)] = 1; + } + tmp = tmp->next; + } + } + } +} + +void deleteEdge(listNode **g, char src, char dist) { + listNode *ptr = g[ch2digit(src)]; + while (ptr != NULL && ptr->next != NULL) { + if (ptr->next->ID == dist) { + ptr->next = ptr->next->next; + } + ptr = ptr->next; + } +} + +int main(void) { + queue *q = newQueue(); + listNode **g = makeGraph(); + + char src, dist; + scanf("%c,%c", &src, &dist); + deleteEdge(g, src, dist); + + topoSort(g); + + return 0; +} diff --git a/semester3/pset6/7-3-Shortest-Path.c b/semester3/pset6/7-3-Shortest-Path.c new file mode 100644 index 0000000..09ebb36 --- /dev/null +++ b/semester3/pset6/7-3-Shortest-Path.c @@ -0,0 +1,122 @@ +#include +#include +#define SIZE 7 +#define MAX 100 + +typedef struct node { + int index, + dist; // for the starting node, dist means shortest distance from start to + // here, for child nodes, dist means dist(parent, this) + struct node *next; + struct node *parent; +} node; + +node *newNode(int index, int dist) { + node *new = malloc(sizeof(node)); + new->index = index; + new->dist = dist; + new->next = NULL; + new->parent = NULL; + + return new; +} + +void appendEdge(node *src, int index, int dist) { + node *end = newNode(index, dist); + node *ptr = src; + while (ptr->next != NULL) { + ptr = ptr->next; + } + ptr->next = end; +} + +node **makeGraph() { + node **g = malloc(sizeof(node *) * SIZE); + for (int i = 0; i < SIZE; i++) { + g[i] = newNode(i, MAX); + } + appendEdge(g[0], 1, 2); + appendEdge(g[0], 3, 1); + + appendEdge(g[1], 3, 3); + appendEdge(g[1], 4, 10); + + appendEdge(g[2], 0, 4); + appendEdge(g[2], 5, 5); + + appendEdge(g[3], 2, 2); + appendEdge(g[3], 4, 2); + appendEdge(g[3], 5, 8); + appendEdge(g[3], 6, 4); + + appendEdge(g[4], 6, 6); + + appendEdge(g[6], 5, 1); + return g; +} + +int getMinDistance(node **graph, int visited[]) { + int min = MAX, minIndex; + for (int i = 0; i < SIZE; i++) { + if (graph[i]->dist < min && visited[i] == 0) { + min = graph[i]->dist; + minIndex = i; + } + } + return minIndex; +} + +void dijkstra(node **graph, int start) { + int visited[SIZE] = {}; + for (int i = 0; i < SIZE; i++) { + int s = getMinDistance(graph, visited); + // printf("found start: %d\n", s); + + visited[s] = 1; + + node *ptr = graph[s]->next; + + // update distance of unvisited nodes + while (ptr) { + if (visited[ptr->index] == 0 && + graph[ptr->index]->dist > ptr->dist + graph[s]->dist) { + graph[ptr->index]->dist = ptr->dist + graph[s]->dist; + graph[ptr->index]->parent = graph[s]; + // printf("Updated: %d, dist: %d\n", ptr->index, + // graph[ptr->index]->dist); + } + ptr = ptr->next; + } + } +} + +int main(void) { + node **graph = makeGraph(); + + int start, end; + scanf("%d,%d", &start, &end); + start--; + end--; + + // init the start's dist as 0 + graph[start]->dist = 0; + dijkstra(graph, start); + + if (graph[end]->parent == NULL) { + printf("-1"); + } else { + int route[MAX]; + int count = 0; + node *ptr = graph[end]; + while (ptr) { + route[count++] = ptr->index; + ptr = ptr->parent; + } + + for (int i = count - 1; i >= 0; i--) { + printf("%d,", route[i] + 1); + } + } + + return 0; +}