diff --git a/report.html b/report.html new file mode 100644 index 0000000..687fd90 --- /dev/null +++ b/report.html @@ -0,0 +1,3452 @@ + + +
+ +假设有一个能装入总体积为T
的背包和n
件体积分别为w1,w2,…wn
的物品,能否从n
件物品中挑选若干件恰好装背包,即使w1+w2+…+wm=T
,要求找出所有满足上述条件的解。
+例如:当T=10
,各件物品的体积{1,8,4,3,5,2}
时,可找到下列4
组解:
(1,4,3,2)
(1,4,5)
(8,2)
(3,5,2)
可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后,顺序选取物品装入背包,若已选取i
件物品后未满,则继续选取第i+1
件,若该件物品“太大”不能装入,则弃之,继续选取下一件,直至背包装满为。
如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入的物品“不合适”,应将它取出“弃之一”,继续再从“它之后”的物品中选取,如此重复,直到求得满足条件的解,或者无解。
+由于回溯求解的规则是“后进先出”,自然要用到“栈”。 +进一步考虑:如果每件物品都有体积和价值,背包又有大小限制,求解背包中存放物品总价值最大的问题解---最优解或近似最优解。
+一个能装入总体积为T
的背包和n
件体积分别为w1,w2,…wn
的物品,能否从n
件物品中挑选若干件恰好装背包,即使w1+w2+…+wm=T
相当于取一个向量 = ,其中 ,使得 ,求所有满足条件的 。
+使用暴力 dfs
搜索,搜索每一件物品的选择情况,符合条件时输出。
使用 sum+w[k]<=T
进行剪枝,提高运行速度
总情况数为 ,时间复杂度为 。
+#include <stdio.h>
+#include <stdlib.h>
+#define MAX_N 100
+
+int T;
+int n;
+int w[MAX_N];
+int x[MAX_N];
+int solution_count = 0;
+
+// dfs函数,t为当前搜索的层数,sum为当前已经选择的物品的体积和,k为当前搜索的物品编号
+void dfs(int t, int sum, int k) {
+ if (sum == T) {
+ solution_count++;
+ if (solution_count > 50)
+ return;
+ // 输出解
+ int *re = malloc(sizeof(int) * k);
+ int j = 0;
+ for (int i = 0; i < k; i++) {
+ if (x[i]) {
+ re[j++] = w[i];
+ }
+ }
+ for (int i = 0; i < j; i++) {
+ printf("%d ", re[i]);
+ }
+ printf("\n");
+ } else if (sum < T && k < n) {
+ // 剪枝,提高运行速度
+ if (sum + w[k] <= T) {
+ // 选第k件物品
+ x[k] = 1;
+ dfs(t + 1, sum + w[k], k + 1);
+ }
+ // 不选第k件物品
+ x[k] = 0;
+ dfs(t + 1, sum, k + 1);
+ }
+}
+
+int main() {
+ freopen("data.in", "r", stdin);
+ // freopen("data.out", "w", stdout);
+ scanf("%d", &T);
+ scanf("%d", &n);
+ for (int i = 0; i < n; i++) {
+ scanf("%d", &w[i]);
+ }
+ // 搜索
+ dfs(0, 0, 0);
+ printf("Total Solution Count: %d\n", solution_count);
+ return 0;
+}
+
+
+10
+6
+1 8 4 3 5 2
+
+1 4 3 2
+1 4 5
+8 2
+3 5 2
+Total Solution Count: 4
+
+将题目拓展为背包问题,使用 dp
算法解决
#include <stdio.h>
+#include <stdlib.h>
+
+int T, M, t[105], w[105];
+int dp[1005][1005];
+
+int max(int a, int b) { return a > b ? a : b; }
+
+int main() {
+ freopen("dp.in", "r", stdin);
+ scanf("%d%d", &T, &M);
+ for (int i = 1; i <= M; i++) {
+ scanf("%d%d", &t[i], &w[i]);
+ }
+ dp[0][0] = 0;
+ // dp[i][j]表示前i件物品,体积为j时的最大价值
+ for (int i = 1; i <= M; i++) {
+ for (int j = 1; j <= T; j++) {
+ // 如果第i件物品的体积大于j,那么就不能选第i件物品
+ if (j < t[i])
+ dp[i][j] = dp[i - 1][j];
+ else
+ // 否则就是选或者不选第i件物品的最大值
+ dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - t[i]] + w[i]);
+ }
+ }
+ printf("%d\n", dp[M][T]);
+ // for(int i=1;i<=M;i++){
+ // for(int j=1;j<=T;j++){
+ // printf("%d ",dp[i][j]);
+ // }
+ // printf("\n");
+ // }
+
+ return 0;
+}
+
+10 6
+1 1
+8 4
+4 2
+3 2
+5 3
+2 2
+
+7
+
+一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸。他要把这些东西
+
+全部运到北岸。他面前只有一条小船,船只能容下他和一件物品,另外只有农夫 +才能撑船。如果农夫在场,则狼不能吃羊,羊不能吃白菜,否则狼会吃羊,羊会 +吃白菜,所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,而 +狼不吃白菜。请求出农夫将所有的东西运过河的方案。
+求解这个问题的简单方法是一步一步进行试探,每一步搜索所有可能的选择,对前一步合适的选择后再考虑下一步的各种方案。要模拟农夫过河问题,首先需要对问题中的每个角色的位置进行描述。可用4
位二进制数顺序分别表示农夫、狼、白菜和羊的位置。用0表在南岸,1表示在北岸。例如,整数5
(0101
)表示农
+夫和白菜在南岸,而狼和羊在北岸。
现在问题变成:从初始的状态二进制0000
(全部在河的南岸)出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111
(全部到达河的北岸)为最终目标。总状态共16种(0000
到1111
),(或者看成16
个顶点的有向图)可采用广度优先或深度优先的搜索策略---
得到从0000
到1111
的安全路径。
以广度优先为例:整数队列---逐层存放下一步可能的安全状态;Visited[16]数组标记该状态是否已访问过,若访问过,则记录前驱状态值---安全路径。
+最终的过河方案应用汉字显示出每一步的两岸状态。
+使用 dfs
搜索,搜索每一步的选择情况,符合条件时输出。
#include <stdio.h>
+#include <stdlib.h>
+
+int state = 0;
+int v[16];
+char labels[4][16] = {"农夫", "狼", "羊", "菜"};
+int re[16];
+int xx[16];
+int k = 0;
+
+void pt(int command, int state) {
+ int *f = malloc(sizeof(int) * 4);
+ for (int i = 0; i < 4; i++) {
+ // 计算每一位的值
+ f[i] = (state >> i) & 1;
+ }
+ // 按照命令输出
+ if (command == 0) {
+ printf("农夫自己过河\n");
+ } else if (command == 1) {
+ printf("带 狼 过河\n");
+ } else if (command == 2) {
+ printf("带 羊 过河\n");
+ } else if (command == 3) {
+ printf("带 菜 过河\n");
+ }
+ printf("A > ");
+ for (int i = 0; i < 4; i++) {
+ if (f[i] == 1) {
+ printf("%s ", labels[i]);
+ }
+ }
+ printf("\n");
+ printf("B > ");
+ for (int i = 0; i < 4; i++) {
+ if (f[i] == 0) {
+ printf("%s ", labels[i]);
+ }
+ }
+ printf("\n---------------------\n");
+}
+
+int validate_state(int state) {
+ int *f = malloc(sizeof(int) * 4);
+ for (int i = 0; i < 4; i++) {
+ f[i] = (state >> i) & 1;
+ // printf("%d ", f[i]);
+ }
+ // printf("\n");
+ if (!f[1] ^ f[2] && f[0] ^ f[1]) {
+ return 0;
+ } else if (!f[2] ^ f[3] && f[0] ^ f[2]) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+int trans(int x, int undo) {
+ // 0 表示农夫自己过河
+ // 1 表示带狼过河
+ // 2 表示带羊过河
+ // 3 表示带菜过河
+ int tmp_state = state;
+ if (x == 1) {
+ tmp_state = state ^ 3;
+ } else if (x == 2) {
+ tmp_state = state ^ 5;
+ } else if (x == 3) {
+ tmp_state = state ^ 9;
+ } else {
+ tmp_state = state ^ 1;
+ }
+ // pt(state);
+ // printf("%d > ", x);
+ // pt(tmp_state);
+ if (undo) {
+ v[tmp_state] = 0;
+ state = tmp_state;
+ re[--k] = 0;
+ xx[k] = 0;
+ return 1;
+ }
+ if (validate_state(tmp_state) == 0) {
+ return 0;
+ }
+ if (v[tmp_state] == 0) {
+ v[tmp_state] = 1;
+ state = tmp_state;
+ xx[k] = x;
+ re[k++] = state;
+ return 1;
+ }
+ return 0;
+}
+
+void dfs() {
+ // printf(">> %d\n", state);
+ if (state == 15) {
+ for (int i = 0; i < k; i++) {
+ pt(xx[i], re[i]);
+ }
+ printf("\n");
+ return;
+ }
+ if (trans(0, 0)) {
+ dfs();
+ trans(0, 1);
+ }
+ if (trans(1, 0)) {
+ dfs();
+ trans(1, 1);
+ }
+ if (trans(2, 0)) {
+ dfs();
+ trans(2, 1);
+ }
+ if (trans(3, 0)) {
+ dfs();
+ trans(3, 1);
+ }
+}
+
+int main() {
+ // freopen("data.in", "r", stdin);
+ // freopen("data.out", "w", stdout);
+ v[0] = 1;
+ dfs();
+ return 0;
+}
+
+无
+
+带 羊 过河
+A > 农夫 羊
+B > 狼 菜
+---------------------
+农夫自己过河
+A > 羊
+B > 农夫 狼 菜
+---------------------
+带 狼 过河
+A > 农夫 狼 羊
+B > 菜
+---------------------
+带 羊 过河
+A > 狼
+B > 农夫 羊 菜
+---------------------
+带 菜 过河
+A > 农夫 狼 菜
+B > 羊
+---------------------
+农夫自己过河
+A > 狼 菜
+B > 农夫 羊
+---------------------
+带 羊 过河
+A > 农夫 狼 羊 菜
+B >
+---------------------
+
+设计一个支持基本计算统计功能和其它一些表格管理/处理功能的软件,使用 +户可在该软件的支持下,用交互方式进行表格建立、数据输入、数据编辑及其它 +一些表格操作。即类似于简易Execel表格处理软件。
+参考代码中的 main.c
,使用 TableInfo
结构体存储表格信息,使用 key.h
存储键盘按键的宏定义,使用 conio.h
实现光标移动,使用 stdlib.h
实现 malloc
函数,使用 string.h
实现 strcpy
函数,使用 stdio.h
实现 printf
函数,使用 math.h
实现 atoi
函数。
大致如下,具体交互功能请运行代码
+key.h
#define KEY_LEFT_ARROW 0x4B // 左箭头
+#define KEY_UP_ARROW 0x48 // 上箭头
+#define KEY_RIGHT_ARROW 0x4D // 右箭头
+#define KEY_DOWN_ARROW 0x50 // 下箭头
+#define KEY_ENTER 0x0D // 回车
+#define KEY_ESC 0x1B // ESC
+
+main.c
#include "key.h"
+#include <conio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// 一些常量
+#define MAX_COLUMN 20
+#define MAX_ROW 20
+#define MAX_COLUMN_WIDTH 10
+#define MAX_DATA_LENGTH 100
+#define MAX_TICK 200
+#define MAX_MESSAGE_LENGTH 100
+#define FUNCTION_NUM 8
+
+// tick 已废弃
+int tick = 0;
+// 当前光标所在位置
+int current_x = 0;
+int current_y = 0;
+// 当前是否关闭
+int alive = 1;
+// 选择模式是否启用
+int select_mode = 0;
+// 从哪里进入选择模式
+int select_entry = 0;
+// 当前的输入模式
+int input_mode = 0;
+
+// 底部的功能列表
+char functions[FUNCTION_NUM][100] = {"Save", "Load", "Sum", "Average",
+ "Max", "Min", "Sort", "Exit"};
+
+// 当前的消息
+char *message = "Hi~";
+
+// 表格信息
+typedef struct {
+ int current_width;
+ int current_height;
+ int column_width[MAX_COLUMN];
+ char data[MAX_ROW][MAX_COLUMN][MAX_DATA_LENGTH];
+} TableInfo;
+
+// 常用函数
+int max(int a, int b) { return a > b ? a : b; }
+
+int min(int a, int b) { return a < b ? a : b; }
+
+// 计算一个 int 的长度
+int int_length(int num) {
+ if (num == 0)
+ return 1;
+ int length = 0;
+ while (num) {
+ num /= 10;
+ length++;
+ }
+ return length;
+}
+
+// 判断一个字符串是否全是数字
+int is_string_all_number(char *str) {
+ int length = strlen(str);
+ for (int i = 0; i < length; i++) {
+ if (str[i] < '0' || str[i] > '9') {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+// 判断一行或一列是否全是数字
+int is_index_all_number(TableInfo *table, int type, int index) {
+ if (type == 0) {
+ // 行
+ index = index - 1;
+ for (int i = 0; i < table->current_width; i++) {
+ if (strlen(table->data[index][i]) > 0) {
+ if (!is_string_all_number(table->data[index][i])) {
+ return 0;
+ }
+ }
+ }
+ } else {
+ // 列
+ index = index - 'A';
+ for (int i = 0; i < table->current_height; i++) {
+ if (strlen(table->data[i][index]) > 0) {
+ if (!is_string_all_number(table->data[i][index])) {
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+// 交换两列
+void changeTwoColumn(TableInfo *table, int column1, int column2) {
+ // 验证两列是否合法且不等
+ if (column1 == column2 || column1 < 0 || column2 < 0 ||
+ column1 >= table->current_width || column2 >= table->current_width) {
+ return;
+ }
+ char tmp[MAX_DATA_LENGTH];
+ for (int i = 0; i < table->current_height; i++) {
+ strcpy(tmp, table->data[i][column1]);
+ strcpy(table->data[i][column1], table->data[i][column2]);
+ strcpy(table->data[i][column2], tmp);
+ }
+}
+
+// 交换两行
+void changeTwoRow(TableInfo *table, int row1, int row2) {
+ // 验证两行是否合法且不等
+ if (row1 == row2 || row1 < 0 || row2 < 0 || row1 >= table->current_height ||
+ row2 >= table->current_height) {
+ return;
+ }
+ char tmp[MAX_DATA_LENGTH];
+ for (int i = 0; i < table->current_width; i++) {
+ strcpy(tmp, table->data[row1][i]);
+ strcpy(table->data[row1][i], table->data[row2][i]);
+ strcpy(table->data[row2][i], tmp);
+ }
+}
+
+// 自定义支持大小写敏感的字符串比较函数
+int str_cmp(char *str1, char *str2, int case_sensitive) {
+ if (case_sensitive) {
+ return strcmp(str1, str2);
+ } else {
+ char *tmp_str1 = (char *)malloc(sizeof(char) * strlen(str1));
+ char *tmp_str2 = (char *)malloc(sizeof(char) * strlen(str2));
+ strcpy(tmp_str1, str1);
+ strcpy(tmp_str2, str2);
+ for (int i = 0; i < strlen(tmp_str1); i++) {
+ if (tmp_str1[i] >= 'A' && tmp_str1[i] <= 'Z') {
+ tmp_str1[i] += 32;
+ }
+ }
+ for (int i = 0; i < strlen(tmp_str2); i++) {
+ if (tmp_str2[i] >= 'A' && tmp_str2[i] <= 'Z') {
+ tmp_str2[i] += 32;
+ }
+ }
+ int result = strcmp(tmp_str1, tmp_str2);
+ free(tmp_str1);
+ free(tmp_str2);
+ return result;
+ }
+}
+
+// 判断一个 index 是否合法
+int check_index_valid(TableInfo *table, char *index) {
+ // 合法的 index 应该是 A1,A23 这样的格式
+ int length = strlen(index);
+ if (length == 0) {
+ return 0;
+ }
+
+ if (index[0] >= 'A' && index[0] <= 'A' + table->current_width - 1) {
+ // 列号合法
+ int row = 0;
+ for (int i = 1; i < length; i++) {
+ if (index[i] < '0' || index[i] > '9') {
+ return 0;
+ }
+ row = row * 10 + index[i] - '0';
+ }
+ if (row >= 1 && row <= table->current_height) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// 传入实际的 index
+int check_valid_formatter(TableInfo *table, int x, int y) {
+ // 合法的公示应该以 = 开头,并且只包含 + - 和
+ char *data = malloc(sizeof(char) * MAX_DATA_LENGTH);
+ strcpy(data, table->data[y][x]);
+ if (data[0] != '=') {
+ return 0;
+ }
+ int length = strlen(data);
+ char *tmp_data = malloc(sizeof(char) * MAX_DATA_LENGTH);
+ for (int i = 1; i < length; i++) {
+ if (data[i] == ' ')
+ continue;
+ // 获取 =,-,+,\n 之间的字符串
+ int j = i;
+ while (j < length && data[j] != '=' && data[j] != '-' &&
+ data[j] != '+' && data[j] != '\n') {
+ tmp_data[j - i] = data[j];
+ j++;
+ }
+ tmp_data[j - i] = '\0';
+ // 判断是否是合法的 index
+ if (tmp_data[0] >= 'A' && tmp_data[0] <= 'Z') {
+ if (!check_index_valid(table, tmp_data))
+ return 0;
+ } else {
+ for (int k = 0; k < j - i; k++) {
+ if (tmp_data[k] < '0' || tmp_data[k] > '9') {
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+// 获取是行还是列
+int get_index_type(int index) { return index >> 7; }
+
+// 获取具体的值
+int get_index_value(int index) { return index & 0b01111111; }
+
+// 进入选择模式,选择某行或某列
+int start_select_index(int entry) {
+ message = "Select a row or column";
+ current_x = 0;
+ current_y = 1;
+ select_mode = 1;
+ select_entry = entry;
+}
+
+// 退出选择模式
+void end_select_index(TableInfo *table) {
+ // 一个 8 位数字
+ // 最高位: 0 代表行 1 代表列
+ // 低 7 位: 代表行号或列号对应字符的 ASCII 码
+ int select_value = 0;
+ if (current_x == 0) {
+ // x = 0 表示选择行
+ select_value = 0b00000000 | current_y;
+ } else {
+ // x > 0 表示选择列
+ select_value = 0b10000000 | (current_x + 'A' - 1);
+ }
+ int type = get_index_type(select_value);
+ int value = get_index_value(select_value);
+
+ int ascii_sort = 0;
+ // 0 代表不区分大小写,1 代表区分大小写
+ int case_sensitive = 0;
+
+ // 判断是否和数字操作有关
+ if (select_entry == 2 || select_entry == 3 || select_entry == 4 ||
+ select_entry == 5 || select_entry == 6) {
+ int valid = is_index_all_number(table, type, value);
+ if (!valid) {
+ if (select_entry == 6) {
+ ascii_sort = 1;
+ message =
+ "This row or column is not all number, use ASCII to "
+ "sort!\n Do you want to use Case Sensitive? ([Y]/n): ";
+ // 等待完善:选择大小写敏感
+ // char tmp;
+ // input_mode = 1;
+ // scanf("%c", &tmp);
+ // input_mode = 0;
+ // if (tmp == 'n' || tmp == 'N') {
+ // case_sensitive = 0;
+ // } else {
+ // case_sensitive = 1;
+ // }
+ } else {
+ message = "This row or column is not all number!";
+ return;
+ }
+ }
+ }
+
+ if (select_entry == 2) {
+ // sum
+ int sum = 0;
+ if (type == 0) {
+ // 行
+ value = value - 1;
+ for (int i = 0; i < table->current_width; i++) {
+ if (strlen(table->data[value][i]) > 0) {
+ sum += atoi(table->data[value][i]);
+ }
+ }
+ } else {
+ // 列
+ value = value - 'A';
+ for (int i = 0; i < table->current_height; i++) {
+ if (strlen(table->data[i][value]) > 0) {
+ sum += atoi(table->data[i][value]);
+ }
+ }
+ }
+ char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "Sum: %d", sum);
+ message = tmp_message;
+ } else if (select_entry == 3) {
+ // average
+ int sum = 0;
+ int count = 0;
+ if (type == 0) {
+ // 行
+ value = value - 1;
+ for (int i = 0; i < table->current_width; i++) {
+ if (strlen(table->data[value][i]) > 0) {
+ sum += atoi(table->data[value][i]);
+ count++;
+ }
+ }
+ } else {
+ // 列
+ value = value - 'A';
+ for (int i = 0; i < table->current_height; i++) {
+ if (strlen(table->data[i][value]) > 0) {
+ sum += atoi(table->data[i][value]);
+ count++;
+ }
+ }
+ }
+ char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "Average: %f", (double)sum / count);
+ message = tmp_message;
+ } else if (select_entry == 4) {
+ // max
+ int max_ = -0x7fffffff;
+ if (type == 0) {
+ // 行
+ value = value - 1;
+ for (int i = 0; i < table->current_width; i++) {
+ if (strlen(table->data[value][i]) > 0) {
+ max_ = atoi(table->data[value][i]) > max_
+ ? atoi(table->data[value][i])
+ : max_;
+ }
+ }
+ } else {
+ // 列
+ value = value - 'A';
+ for (int i = 0; i < table->current_height; i++) {
+ if (strlen(table->data[i][value]) > 0) {
+ max_ = atoi(table->data[i][value]) > max_
+ ? atoi(table->data[i][value])
+ : max_;
+ }
+ }
+ }
+ char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "Max: %d", max_);
+ message = tmp_message;
+ } else if (select_entry == 5) {
+ // min
+ int min_ = 0x7fffffff;
+ if (type == 0) {
+ // 行
+ value = value - 1;
+ for (int i = 0; i < table->current_width; i++) {
+ if (strlen(table->data[value][i]) > 0) {
+ min_ = atoi(table->data[value][i]) < min_
+ ? atoi(table->data[value][i])
+ : min_;
+ }
+ }
+ } else {
+ // 列
+ value = value - 'A';
+ for (int i = 0; i < table->current_height; i++) {
+ if (strlen(table->data[i][value]) > 0) {
+ min_ = atoi(table->data[i][value]) < min_
+ ? atoi(table->data[i][value])
+ : min_;
+ }
+ }
+ }
+ char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "Min: %d", min_);
+ message = tmp_message;
+ } else if (select_entry == 6) {
+ // sort
+ if (type == 0) {
+ // 行
+ value = value - 1;
+ for (int i = 0; i < table->current_width; i++) {
+ for (int j = i + 1; j < table->current_width; j++) {
+ if (!ascii_sort) {
+ if (atoi(table->data[value][i]) >
+ atoi(table->data[value][j])) {
+ changeTwoColumn(table, i, j);
+ }
+ message = "Sorted by number!";
+ } else {
+ if (str_cmp(table->data[value][i],
+ table->data[value][j],
+ case_sensitive) > 0) {
+ changeTwoColumn(table, i, j);
+ }
+ message = "Sorted by ASCII!";
+ }
+ }
+ }
+ } else {
+ // 列
+ value = value - 'A';
+ for (int i = 0; i < table->current_height; i++) {
+ for (int j = i + 1; j < table->current_height; j++) {
+ if (!ascii_sort) {
+ if (atoi(table->data[i][value]) >
+ atoi(table->data[j][value])) {
+ changeTwoRow(table, i, j);
+ }
+ message = "Sorted by number!";
+ } else {
+ if (str_cmp(table->data[i][value],
+ table->data[j][value],
+ case_sensitive) > 0) {
+ changeTwoRow(table, i, j);
+ }
+ message = "Sorted by ASCII!";
+ }
+ }
+ }
+ }
+ } else {
+ // 选择行或列
+ if (type == 0) {
+ // 行
+ value = value - 1;
+ char *tmp_message =
+ (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "Selected row: %d", value + 1);
+ message = tmp_message;
+ } else {
+ // 列
+ value = value - 'A';
+ char *tmp_message =
+ (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "Selected column: %c", value + 'A');
+ message = tmp_message;
+ }
+ }
+
+ // char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ // sprintf(tmp_message, "Selected: %d,%c", get_index_type(select_value),
+ // get_index_value(select_value));
+ // message = tmp_message;
+
+ select_mode = 0;
+ current_y = -1;
+ current_x = select_entry;
+}
+
+// 将 int 转换为字符串
+char *int_to_string(int num) {
+ char *str = (char *)malloc(sizeof(char) * 100);
+ sprintf(str, "%d", num);
+ return str;
+}
+
+// 初始化表格
+void init_table(int width, int height, int column_width, TableInfo *table) {
+ table->current_width = width;
+ table->current_height = height;
+ for (int i = 0; i < width; i++) {
+ table->column_width[i] = column_width;
+ }
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ table->data[i][j][0] = '\0';
+ }
+ }
+}
+
+// 计算公式
+int cal_formula(TableInfo *table, int x, int y) {
+ char *data = malloc(sizeof(char) * MAX_DATA_LENGTH);
+ strcpy(data, table->data[y][x]);
+ int length = strlen(data);
+ char *tmp_data = malloc(sizeof(char) * MAX_DATA_LENGTH);
+ int result = 0;
+ for (int i = 1; i < length; i++) {
+ if (data[i] == ' ')
+ continue;
+ // 标注 -
+ int minus = 0;
+ // 获取 =,-,+,\n 之间的字符串
+ int j = i;
+ while (j < length && data[j] != '=' && data[j] != '-' &&
+ data[j] != '+' && data[j] != '\n') {
+ tmp_data[j - i] = data[j];
+ j++;
+ }
+ tmp_data[j - i] = '\0';
+ // 判断是否是 -
+ if (data[i - 1] == '-') {
+ minus = 1;
+ }
+ // 判断是否是合法的 index
+ if (tmp_data[0] >= 'A' && tmp_data[0] <= 'Z') {
+ if (!check_index_valid(table, tmp_data))
+ return -1;
+ // 0 表示 列,剩下的是行
+ int col = tmp_data[0] - 'A';
+ int row = 0;
+ for (int k = 1; k < strlen(tmp_data); k++) {
+ row = row * 10 + tmp_data[k] - '0';
+ }
+ // 判断 table->data[row - 1][col] 是否是数字
+ if (strlen(table->data[row - 1][col]) == 0) {
+ return -1;
+ }
+ if (!is_string_all_number(table->data[row - 1][col])) {
+ return -1;
+ }
+ if (minus) {
+ result -= atoi(table->data[row - 1][col]);
+ } else {
+ result += atoi(table->data[row - 1][col]);
+ }
+ } else {
+ for (int k = 0; k < j - i; k++) {
+ if (tmp_data[k] < '0' || tmp_data[k] > '9') {
+ return -1;
+ }
+ }
+ if (minus) {
+ result -= atoi(tmp_data);
+ } else {
+ result += atoi(tmp_data);
+ }
+ }
+ i += j - i;
+ }
+ return result;
+}
+
+// 输出表格
+void printTable(TableInfo *table) {
+ system("cls");
+ printf("Table v0.2 by Luthics\n");
+ int max_l = int_length(table->current_height) + 1;
+ // render table
+ for (int i = -1; i < table->current_height; i++) {
+ for (int j = -1; j < table->current_width; j++) {
+ printf("+");
+ if (j == -1) {
+ for (int k = 0; k < max_l; k++) {
+ printf("-");
+ }
+ continue;
+ }
+ for (int k = 0; k < table->column_width[j]; k++) {
+ printf("-");
+ }
+ }
+ printf("+\n");
+ if (i == -1) {
+ // 输出 A-Z 的列名
+ for (int j = -1; j < table->current_width; j++) {
+ if (j == -1) {
+ printf("|");
+ for (int k = 0; k < max_l; k++) {
+ printf(" ");
+ }
+ continue;
+ }
+ printf("|");
+ for (int k = 0; k < table->column_width[j] - 1; k++) {
+ printf(" ");
+ }
+ if (select_mode) {
+ if (current_x - 1 == j && current_y == 0) {
+ // RED
+ printf("\033[31m");
+ // BOLD
+ printf("\033[1m");
+ }
+ }
+ printf("%c", 'A' + j);
+ if (select_mode) {
+ if (current_x - 1 == j && current_y == 0) {
+ // RESET
+ printf("\033[0m");
+ }
+ }
+ }
+ printf("|\n");
+ continue;
+ }
+ for (int j = -1; j < table->current_width; j++) {
+ if (j == -1) {
+ printf("|");
+ int data_length = int_length(i + 1);
+ for (int k = 0; k < max_l - data_length; k++) {
+ printf(" ");
+ }
+ if (select_mode) {
+ if (current_x == 0 && current_y == i + 1) {
+ // RED
+ printf("\033[31m");
+ // BOLD
+ printf("\033[1m");
+ }
+ }
+ printf("%d", i + 1);
+ if (select_mode) {
+ if (current_x == 0 && current_y == i + 1) {
+ // RESET
+ printf("\033[0m");
+ }
+ }
+ continue;
+ }
+ printf("|");
+ int data_length =
+ table->data[i][j] == NULL ? 0 : strlen(table->data[i][j]);
+
+ if (data_length == 0) {
+ if (i == current_y && j == current_x && !select_mode) {
+ printf("_");
+ } else {
+ printf(" ");
+ }
+ for (int k = 0; k < table->column_width[j] - 1; k++) {
+ printf(" ");
+ }
+ } else {
+ int formatter = 0;
+ if (table->data[i][j][0] == '=') {
+ formatter = 1;
+ }
+ int add_ = 0;
+ if (select_mode) {
+ if (current_x == j + 1 || current_y == i + 1) {
+ // RED
+ printf("\033[31m");
+ // BOLD
+ printf("\033[1m");
+ }
+ } else if (i == current_y && j == current_x) {
+ // RED
+ printf("\033[31m");
+ // BOLD
+ printf("\033[1m");
+ } else if (formatter) {
+ // BLUE
+ printf("\033[34m");
+ // BOLD
+ printf("\033[1m");
+ }
+ int formatter_success = 0;
+ if (formatter && !select_mode &&
+ !(i == current_y && j == current_x)) {
+ // todo 先计算后渲染,修复列宽不合适的bug
+ int data = cal_formula(table, j, i);
+ if (data == -1) {
+ formatter_success = 0;
+ } else {
+ char *tmp_data =
+ (char *)malloc(sizeof(char) * MAX_DATA_LENGTH);
+ sprintf(tmp_data, "%d", data);
+ data_length = strlen(tmp_data);
+ printf("%s", tmp_data);
+ table->column_width[j] =
+ max(table->column_width[j], strlen(tmp_data));
+ formatter_success = 1;
+ }
+ }
+ if (!formatter_success) {
+ for (int k = 0; k < data_length; k++) {
+ printf("%c", table->data[i][j][k]);
+ }
+ }
+ if (select_mode) {
+ if (current_x == j + 1 || current_y == i + 1) {
+ // RESET
+ printf("\033[0m");
+ }
+ } else if (i == current_y && j == current_x) {
+ // RESET
+ printf("\033[0m");
+ // 如果还有空间,就补上下划线
+ if (table->column_width[j] - data_length > 0) {
+ printf("_");
+ add_ = 1;
+ }
+ } else if (formatter) {
+ // Reset
+ printf("\033[0m");
+ }
+ if (formatter) {
+ // 补上空格
+ for (int k = 0; k < table->column_width[j] - data_length;
+ k++) {
+ printf(" ");
+ }
+ } else {
+ for (int k = 0;
+ k < table->column_width[j] - data_length - add_; k++) {
+ printf(" ");
+ }
+ }
+ }
+ }
+ printf("|\n");
+ }
+ for (int j = -1; j < table->current_width; j++) {
+ if (j == -1) {
+ printf("+");
+ for (int k = 0; k < max_l; k++) {
+ printf("-");
+ }
+ continue;
+ }
+ printf("+");
+ for (int k = 0; k < table->column_width[j]; k++) {
+ printf("-");
+ }
+ }
+ printf("+\n");
+
+ // render functions
+ for (int i = 0; i < FUNCTION_NUM; i++) {
+ if (current_y == -1 && i == current_x) {
+ // RED
+ printf("\033[31m");
+ // BOLD
+ printf("\033[1m");
+ }
+ printf("%s", functions[i]);
+ if (current_y == -1 && i == current_x) {
+ // RESET
+ printf("\033[0m");
+ }
+ if (i != FUNCTION_NUM - 1) {
+ printf(" ");
+ }
+ }
+ printf("\n");
+ printf("%s\n", message);
+}
+
+// 判断数据文件是否存在
+int is_data_file_exist() {
+ FILE *fp = fopen("table.dat", "r");
+ if (fp == NULL) {
+ return 0;
+ } else {
+ fclose(fp);
+ return 1;
+ }
+}
+
+// 从文件中读取表格信息
+TableInfo load_table_from_file(char *filename) {
+ TableInfo table;
+ FILE *fp = fopen(filename, "r");
+ fread(&table, sizeof(TableInfo), 1, fp);
+ fclose(fp);
+ return table;
+}
+
+// 将表格信息写入文件
+int save_table_to_file(char *filename, TableInfo table) {
+ FILE *fp = fopen(filename, "w");
+ fwrite(&table, sizeof(TableInfo), 1, fp);
+ fclose(fp);
+ return 0;
+}
+
+// 设置单元格的值
+void setCell(TableInfo *table, int row, int column, char *data) {
+ if (row >= table->current_height || column >= table->current_width ||
+ row < 0 || column < 0) {
+ return;
+ }
+ strcpy(table->data[row][column], data);
+ if (strlen(data) > table->column_width[column]) {
+ table->column_width[column] = strlen(data);
+ }
+}
+
+// 获取单元格的值
+int get_max_width_in_a_column(TableInfo *table, int column) {
+ int max_width = 0;
+ for (int i = 0; i < table->current_height; i++) {
+ int data_length =
+ table->data[i][column] == NULL ? 0 : strlen(table->data[i][column]);
+ if (data_length > max_width) {
+ max_width = data_length;
+ }
+ }
+ return max(max_width, table->column_width[column]);
+}
+
+// 向单元格中添加字符
+void add_char_to_cell(TableInfo *table, int row, int column, char c) {
+ if (row >= table->current_height || column >= table->current_width ||
+ row < 0 || column < 0) {
+ return;
+ }
+ int data_length = strlen(table->data[row][column]);
+ if (data_length < MAX_DATA_LENGTH - 1) {
+ table->data[row][column][data_length] = c;
+ table->data[row][column][data_length + 1] = '\0';
+ table->column_width[column] = get_max_width_in_a_column(table, column);
+ }
+}
+
+// 从单元格中删除字符
+void del_char_from_cell(TableInfo *table, int row, int column) {
+ if (row >= table->current_height || column >= table->current_width ||
+ row < 0 || column < 0) {
+ return;
+ }
+ int data_length = strlen(table->data[row][column]);
+ if (data_length > 0) {
+ table->data[row][column][data_length - 1] = '\0';
+ table->column_width[column] = get_max_width_in_a_column(table, column);
+ }
+}
+
+// 返回 1 代表响应成功
+// 返回 0 代表响应失败
+int handleKeyPress(int key, TableInfo *table) {
+ int status = 0;
+ if (key == 224) { // 特殊键
+ key = getch(); // 获取特殊键码
+ if (key == KEY_LEFT_ARROW) {
+ if (select_mode) {
+ // 选择模式,0,0是左上角,0,1 0,2 0,3 代表每行行号 1,0 2,0 3,0
+ // 代表每列列号
+ if (current_y == 0) {
+ if (current_x > 1)
+ current_x--;
+ else
+ current_x = table->current_width;
+ }
+ if (current_x == 0) {
+ current_y = 0;
+ current_x = table->current_width;
+ }
+ status = 1;
+ } else {
+ if (current_x > 0) {
+ current_x--;
+ } else if (current_x == 0) {
+ if (current_y == -1) {
+ current_x = FUNCTION_NUM - 1;
+ } else {
+ current_x = table->current_width - 1;
+ }
+ }
+ status = 1;
+ }
+ }
+ if (key == KEY_RIGHT_ARROW) {
+ if (select_mode) {
+ if (current_y == 0) {
+ if (current_x < table->current_width)
+ current_x++;
+ else
+ current_x = 1;
+ }
+ if (current_x == 0) {
+ current_y = 0;
+ current_x = 1;
+ }
+ status = 1;
+ } else {
+ if (current_y == -1) {
+ current_x = (current_x + 1) % FUNCTION_NUM;
+ } else {
+ current_x = (current_x + 1) % table->current_width;
+ }
+ status = 1;
+ }
+ }
+ if (key == KEY_UP_ARROW) {
+ if (select_mode) {
+ if (current_x == 0) {
+ if (current_y > 1)
+ current_y--;
+ else
+ current_y = table->current_height;
+ }
+ if (current_y == 0) {
+ current_x = 0;
+ current_y = table->current_height;
+ }
+ status = 1;
+ } else {
+ if (current_y > 0) {
+ current_y--;
+ } else if (current_y == 0) {
+ current_y = -1;
+ current_x = min(FUNCTION_NUM - 1, current_x);
+ } else if (current_y == -1) {
+ current_y = table->current_height - 1;
+ current_x = min(table->current_width - 1, current_x);
+ }
+ status = 1;
+ }
+ }
+ if (key == KEY_DOWN_ARROW) {
+ if (select_mode) {
+ if (current_x == 0) {
+ if (current_y < table->current_height)
+ current_y++;
+ else
+ current_y = 1;
+ }
+ if (current_y == 0) {
+ current_x = 0;
+ current_y = 1;
+ }
+ status = 1;
+ } else {
+ if (current_y < table->current_height - 1 && current_y >= 0) {
+ current_y++;
+ } else if (current_y == table->current_height - 1) {
+ // TO FUNCTIONS AREA
+ current_y = -1;
+ current_x = min(FUNCTION_NUM - 1, current_x);
+ } else if (current_y == -1) {
+ current_y = 0;
+ current_x = min(table->current_width - 1, current_x);
+ }
+ status = 1;
+ }
+ }
+ } else {
+ // ctrl + c
+ if (key == 3) {
+ alive = 0;
+ message = "Bye!";
+ status = 1;
+ }
+ // ctrl + s
+ if (key == 19) {
+ save_table_to_file("table.dat", *table);
+ message = "Saved!";
+ status = 1;
+ }
+ if (select_mode) {
+ // ENTER
+ if (key == KEY_ENTER) {
+ end_select_index(table);
+ status = 1;
+ }
+ // ESC
+ if (key == KEY_ESC) {
+ select_mode = 0;
+ current_y = -1;
+ current_x = select_entry;
+ message = "Canceled!";
+ status = 1;
+ }
+ } else {
+ // 判断 key 是可打印字符
+ if (key >= 32 && key <= 126) {
+ add_char_to_cell(table, current_y, current_x, key);
+ status = 1;
+ }
+ // 退格键
+ if (key == 8) {
+ del_char_from_cell(table, current_y, current_x);
+ status = 1;
+ }
+ // ENTER
+ if (key == KEY_ENTER) {
+ if (current_y == -1) {
+ if (current_x == 0) {
+ save_table_to_file("table.dat", *table);
+ message = "Saved!";
+ }
+ if (current_x == 1) {
+ *table = load_table_from_file("table.dat");
+ message = "Loaded!";
+ }
+ if (current_x == 2) {
+ start_select_index(2);
+ }
+ if (current_x == 3) {
+ start_select_index(3);
+ }
+ if (current_x == 4) {
+ start_select_index(4);
+ }
+ if (current_x == 5) {
+ start_select_index(5);
+ }
+ if (current_x == 6) {
+ start_select_index(6);
+ }
+ if (current_x == 7) {
+ alive = 0;
+ message = "Bye!";
+ }
+ } else {
+ // 如果以 = 开头
+ if (table->data[current_y][current_x][0] == '=') {
+ if (!check_valid_formatter(table, current_x,
+ current_y)) {
+ message = "Not a valid formatter!";
+ }
+ }
+ }
+ }
+ }
+ }
+
+ int debug = 0;
+ if (debug) {
+ char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
+ sprintf(tmp_message, "x: %d, y: %d", current_x, current_y);
+ message = tmp_message;
+ }
+ return status;
+}
+
+int main() {
+ TableInfo table;
+ int load_from_file = 0;
+
+ // 先判断是否有数据文件
+ if (is_data_file_exist()) {
+ char tmp;
+ // 询问是否从文件中读取
+ printf("Load from file? ([Y]/n): ");
+ scanf("%c", &tmp);
+ if (tmp == 'n' || tmp == 'N') {
+ load_from_file = 0;
+ } else {
+ load_from_file = 1;
+ }
+ }
+ if (load_from_file) {
+ table = load_table_from_file("table.dat");
+ } else {
+ // 创建新表格
+ printf("Let's create a table!\n");
+ int width = 0, height = 0;
+ int column_width = 0;
+ while (width <= 0 || width > MAX_COLUMN) {
+ printf("Input width (1-%d): ", MAX_COLUMN);
+ scanf("%d", &width);
+ }
+ while (height <= 0 || height > MAX_ROW) {
+ printf("Input height (1-%d): ", MAX_ROW);
+ scanf("%d", &height);
+ }
+ while (column_width <= 0 || column_width > MAX_COLUMN_WIDTH) {
+ printf("Input column width (1-%d): ", MAX_COLUMN_WIDTH);
+ scanf("%d", &column_width);
+ }
+
+ init_table(width, height, column_width, &table);
+ }
+ // 把第一行第一列的单元格设置为 Hello
+ setCell(&table, 0, 0, "Hello");
+
+ // 主循环
+ while (alive) {
+ printTable(&table);
+ // drawGUI(currentSelection);
+
+ int keyPressed = getch(); // 获取键盘输入
+ handleKeyPress(keyPressed, &table);
+
+ // tick = (tick + 1) % MAX_TICK;
+ }
+
+ // 询问是否保存
+ int save_to_file = 0;
+ char tmp;
+ printf("Save to file? ([Y]/n): ");
+ scanf("%c", &tmp);
+ if (tmp == 'n' || tmp == 'N') {
+ save_to_file = 0;
+ } else {
+ save_to_file = 1;
+ }
+ if (save_to_file) {
+ save_table_to_file("table.dat", table);
+ }
+ return 0;
+}
+
+设在初始状态下在国际象棋的棋盘上没有任何棋子(这里的棋子指皇后棋子)。然后顺序在第1
行,第2
行……第8
行上布放棋子。在每一行中共有8
个可选择的位置,但在任一时刻棋盘的合法布局都必须满足3
个限制条件
编写求解并输出此问题的一个合法布局的程序。
+在第i
行布放棋子时,从第1
列到第8
列逐列考察。当在第i
行第j
列布放棋子时,需要考察布放棋子后在行方向、列方向、正斜线和反斜线方向上的布局状态是否合法,若该棋子布放合法,再递归求解在第i+1
行布放棋子;若该棋子布放不合法,移去这个棋子,恢复布放该棋子前的状态,然后再试探在第i
行第j+1
列布放棋子。
使用回溯法,从第一行开始,每一行都有 n
个选择,如果选择合法,就继续下一行,否则就回溯到上一行,重新选择。
参考 洛谷 P1219 实现的 n
皇后问题
#include <stdio.h>
+#include <stdlib.h>
+
+// 每行每列每个对角线是否被占用
+int ans, a[10005];
+int n;
+int cx[100], zx[100], col[100];
+
+void pt() {
+ for (int i = 1; i <= n; i++) {
+ for (int j = 1; j <= n; j++) {
+ if (a[i] == j) {
+ printf("Q");
+ } else {
+ printf(".");
+ }
+ }
+ printf("\n");
+ }
+ printf("\n");
+ for (int i = 1; i <= n; i++) {
+ printf("%d ", a[i]);
+ }
+ printf("\n");
+}
+
+// 回溯法
+void dfs(int x) {
+ if (x > n) {
+ ans++;
+ if (ans <= 3) {
+ pt();
+ // for (int i = 1; i <= n; i++) {
+ // printf("%d ", a[i]);
+ // }
+ // printf("\n");
+ }
+ return;
+ }
+ for (int i = 1; i <= n; i++) {
+ int l = x + i, r = x - i + 15;
+ // 如果这一列、这一正对角线、这一反对角线都没有被占用
+ if (cx[r] == 0 && zx[l] == 0 && col[i] == 0) {
+ a[x] = i;
+ cx[r] = 1;
+ zx[l] = 1;
+ col[i] = 1;
+ dfs(x + 1);
+ cx[r] = 0;
+ zx[l] = 0;
+ col[i] = 0;
+ }
+ }
+}
+
+int main() {
+ scanf("%d", &n);
+ dfs(1);
+ printf("%d", ans);
+ return 0;
+}
+
+// Ref: P1219 [USACO1.5] 八皇后 Checker Challenge
+// https://www.luogu.com.cn/record/40132197
+
+8
+
+仅输出前三个解
+Q.......
+....Q...
+.......Q
+.....Q..
+..Q.....
+......Q.
+.Q......
+...Q....
+
+1 5 8 6 3 7 2 4
+Q.......
+.....Q..
+.......Q
+..Q.....
+......Q.
+...Q....
+.Q......
+....Q...
+
+1 6 8 3 7 4 2 5
+Q.......
+......Q.
+...Q....
+.....Q..
+.......Q
+.Q......
+....Q...
+..Q.....
+
+1 7 4 6 8 2 5 3
+92
+
+12
+
+仅输出前三个解
+Q...........
+..Q.........
+....Q.......
+.......Q....
+.........Q..
+...........Q
+.....Q......
+..........Q.
+.Q..........
+......Q.....
+........Q...
+...Q........
+
+1 3 5 8 10 12 6 11 2 7 9 4
+Q...........
+..Q.........
+....Q.......
+.........Q..
+.......Q....
+..........Q.
+.Q..........
+...........Q
+.....Q......
+........Q...
+......Q.....
+...Q........
+
+1 3 5 10 8 11 2 12 6 9 7 4
+Q...........
+..Q.........
+....Q.......
+.........Q..
+.......Q....
+..........Q.
+.Q..........
+...........Q
+......Q.....
+........Q...
+...Q........
+.....Q......
+
+1 3 5 10 8 11 2 12 7 9 4 6
+14200
+
+设编号为1,2,…,n(n>0)
个人按顺时针方向围坐一圈,每人持有一个正整数密码。开始时任意给出一个报数上限m
,从第一个人开始顺时针方向自1起顺序报数,报到m
时停止报数,报m
的人出列,将他的密码作为新的m
值,从他在顺时针方向上的下一个人起重新自1
报数;如此下去直到所有人全部出列为止。
设计一个程序模拟此过程,给出出列人的编号序列。
+可考虑不带头结点的单链表结构。
+N=7
,七个人的密码依次为3,1,7,2,4,8,4
.
+初始报数上限值m=20
。
使用循环链表,每次报数到 m 时,就删除这个节点,然后从下一个节点开始重新报数,直到报到这个节点对应的数字,再次循环。
+#include <stdio.h>
+#include <stdlib.h>
+
+int rs[105]; // 每个人的状态
+int n; // 人数
+
+int xcz; // 剩余人数
+int m[105], m0; // 间隔
+
+int zj(int a) {
+ // 寻找下一个活着的人
+ a++;
+ if (a > n)
+ a -= n;
+ while (rs[a] == 0 && xcz > 0) {
+ a++;
+ if (a > n)
+ a -= n;
+ }
+ return a;
+}
+
+int main() {
+ freopen("data.in", "r", stdin);
+ scanf("%d%d", &n, &m0);
+ for (int i = 1; i <= n; i++)
+ scanf("%d", &m[i]);
+ xcz = n;
+ for (int i = 1; i <= n; i++)
+ // 把每个人设置为活着
+ rs[i] = 1;
+ while (m0 > n) {
+ m0 -= n;
+ }
+ for (int i = m0; xcz > 0;) {
+ if (rs[i] == 1) {
+ rs[i] = 0;
+ xcz--;
+ printf("%d ", i);
+ }
+ int ls = m[i];
+ // printf("ls=%d\n", ls);
+ while (ls--)
+ i = zj(i);
+ }
+ return 0;
+}
+
+// Ref: P1996 约瑟夫问题
+// 已修改为实验版本
+
+7 20
+3 1 7 2 4 8 4
+
+6 1 4 7 2 3 5
+
+大学的每个专业都要制定教学计划。假设任何专业都有固定的学习年 +限,每学年含两学期,每学期的时间长度和学分上限值均相等。每个专业 +开设的课程都是固定的,而且课程在开设时间的安排必须满足先修关系。 +每门课程有哪些先修课程是确定的,可以有任意多门,也可以没有。每门 +课恰好占一个学期。试在这样的前提下设计一个教学计划编制程序。
+可设学期总数不超过12,课程总数小于100。如果输入的先修课程号不在该专业开设的课程序列中,则作为错误处理。
+使用拓扑排序,先将课程按照先修课程的数量进行排序,先修课程数量越多的课程越靠前,然后从前往后,如果学期学习数量小于平均值,则将前面的课程往后移动。
+#include <bits/stdc++.h>
+
+using namespace std;
+
+int se; // 学期总数
+int sx; // 学分上限
+int cl; // 课程数量
+int ren[12], fe[12], re[12][105];
+
+struct Class {
+ string id; // 课程编号
+ int sx; // 学分
+ int xq;
+ int sel; // 是否已经选择
+ int pren, nexn; // 先修课程数量
+ int ppren; // use for topo
+ string pre[105]; // 先修课程
+ string next[105]; // 后续课程
+} ss[105];
+
+// 输出具体的课程安排
+void pt(int detail = 0) {
+ // print
+ for (int i = 0; i < cl; i++) {
+ cout << ss[i].id << " " << ss[i].sx << " " << ss[i].pren << " "
+ << ss[i].nexn << endl;
+ if (!detail)
+ continue;
+ if (ss[i].pren > 0) {
+ cout << "pre:" << endl;
+ for (int j = 0; j < ss[i].pren; j++) {
+ cout << ss[i].pre[j] << " ";
+ }
+ cout << endl;
+ }
+ if (ss[i].nexn > 0) {
+ cout << "next:" << endl;
+ for (int j = 0; j < ss[i].nexn; j++) {
+ cout << ss[i].next[j] << " ";
+ }
+ cout << endl;
+ }
+ cout << endl;
+ }
+}
+
+// 寻找 id
+int fd(string id) {
+ for (int i = 0; i < cl; i++) {
+ if (ss[i].id == id) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+// 去除字符串两边空格和换行符
+string ql(string s) {
+ int l = 0, r = s.length() - 1;
+ while (s[l] == ' ' || s[l] == '\n')
+ l++;
+ while (s[r] == ' ' || s[r] == '\n')
+ r--;
+ return s.substr(l, r - l + 1);
+}
+
+// 寻找先修课程的最迟学期
+int xz(int i) {
+ // cout << ss[i].id << " " << ss[i].pren << endl;
+ if (ss[i].pren == 0)
+ return 0;
+ int maxn = 0;
+ for (int j = 0; j < ss[i].pren; j++) {
+ int fid = fd(ss[i].pre[j]);
+ if (ss[fid].xq > maxn) {
+ maxn = ss[fid].xq;
+ }
+ }
+ return maxn + 1;
+}
+
+// 寻找后修课程的最早学期
+int xz2(int i) {
+ if (ss[i].nexn == 0)
+ return se;
+ int minn = se;
+ for (int j = 0; j < ss[i].nexn; j++) {
+ int fid = fd(ss[i].next[j]);
+ if (ss[fid].xq < minn) {
+ minn = ss[fid].xq;
+ }
+ }
+ return minn;
+}
+// 拓扑排序,将排好序的id 放入sorted
+void topo() {
+ int sorted[105] = {0};
+ int cnt = 0;
+ queue<Class *> q;
+ for (int i = 0; i < cl; i++) {
+ if (ss[i].ppren == 0) {
+ q.push(&ss[i]);
+ }
+ }
+ while (!q.empty()) {
+ Class *tmp = q.front();
+ sorted[cnt] = fd(tmp->id);
+ q.pop();
+ cnt++;
+ for (int i = 0; i < tmp->nexn; i++) {
+ ss[fd(tmp->next[i])].ppren--;
+ if (ss[fd(tmp->next[i])].ppren == 0) {
+ q.push(&ss[fd(tmp->next[i])]);
+ }
+ }
+ }
+ if (cnt != cl) {
+ cout << "error" << endl;
+ exit(0);
+ }
+ Class newss[105];
+ // 将 ss 顺序改为 sorted 顺序
+ for (int i = 0; i < cl; i++) {
+ newss[i] = ss[sorted[i]];
+ }
+ for (int i = 0; i < cl; i++) {
+ ss[i] = newss[i];
+ }
+}
+
+void avgf() {
+ // 计算平均每学期学习数量
+ int avg = cl / se;
+ // cout << avg << endl;
+ // 按从后向前,如果学期学习数量小于平均值,则将前面的课程往后移动
+ for (int i = se - 1; i >= 1; i--) {
+ if (ren[i] < avg) {
+ for (int j = i - 1; j >= 0; j--) {
+ // cout << j << " " << ren[j] << endl;
+ if (ren[j] <= 0)
+ continue;
+ int flag = 0;
+ for (int ii = 0; ii < ren[j] && ren[i] < avg; ii++) {
+ int c = re[j][ii];
+ // cout << " " << ss[c].id << " " << xz2(2)<< endl;
+ // cout << c << endl;
+ if (xz2(c) > i) {
+ // 把 c 课程放到 i 学期
+ re[i][ren[i]++] = c;
+ ss[c].xq = i;
+ // 把 c 课程从 j 学期删除
+ for (int jj = ii; jj < ren[j] - 1; jj++) {
+ re[j][jj] = re[j][jj + 1];
+ }
+ ren[j]--;
+ flag = 1;
+ }
+ // 如果 i 学期中的课程数量大于平均值,则跳出循环
+ if (ren[i] >= avg) {
+ break;
+ }
+ if (flag == 1) {
+ ii = -1;
+ flag = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+// 输出最终结果
+void pte() {
+ for (int i = 0; i < se; i++) {
+ if (ren[i] == 0)
+ continue;
+ cout << "学期 " << i + 1 << " 学分 " << fe[i] << " 课程数 " << ren[i]
+ << " 课程:";
+ for (int j = 0; j < ren[i]; j++) {
+ cout << ss[re[i][j]].id << " ";
+ }
+ cout << endl;
+ }
+}
+
+int main() {
+ freopen("in.txt", "r", stdin);
+ cin >> se >> sx;
+ if (se <= 0 || sx <= 0 || se > 6 || sx > 10) {
+ cout << "error" << endl;
+ exit(0);
+ }
+ cin >> cl;
+ if (cl <= 0 || cl > 12) {
+ cout << "error" << endl;
+ exit(0);
+ }
+ for (int i = 0; i < cl; i++) {
+ cin >> ss[i].id;
+ ss[i].id = ql(ss[i].id);
+ }
+ for (int i = 0; i < cl; i++) {
+ // 学分和前置课程
+ cin >> ss[i].sx >> ss[i].pren;
+ ss[i].ppren = ss[i].pren;
+ for (int j = 0; j < ss[i].pren; j++) {
+ string tmp;
+ cin >> tmp;
+ tmp = ql(tmp);
+ if (tmp.size() == 0)
+ continue;
+ int fid = fd(tmp);
+ if (fid == -1) {
+ cout << "error" << endl;
+ exit(0);
+ }
+ ss[i].pre[j] = ss[fid].id;
+ ss[fid].next[ss[fid].nexn++] = ss[i].id;
+ }
+ }
+ // pt(1);
+ topo();
+ // pt(1);
+ for (int i = 0; i < cl; i++) {
+ ss[i].xq = xz(i);
+ }
+ int ttc = 0;
+ for (int i = 0; i < se; i++) {
+ for (int j = 0; j < cl; j++) {
+ // 判断是否已选择
+ if (ss[j].sel == 1) {
+ continue;
+ }
+ // 判断是否学分超过上限
+ if (ss[j].sx + fe[i] > sx) {
+ continue;
+ }
+ // 判断是否先修课程已经学习
+ int flag = 0;
+ for (int k = 0; k < ss[j].pren; k++) {
+ int fid = fd(ss[j].pre[k]);
+ if (ss[fid].sel == 0) {
+ flag = 1;
+ break;
+ }
+ }
+ if (flag == 1) {
+ continue;
+ }
+ // 选择该课程
+ ss[j].sel = 1;
+ fe[i] += ss[j].sx;
+ re[i][ren[i]++] = j;
+ ttc++;
+ }
+ }
+ // 判断是否全部选中
+ if (ttc != cl) {
+ cout << "error" << endl;
+ exit(0);
+ }
+ // for (int i = 0; i < cl; i++) {
+ // cout << ss[i].id << " " << ss[i].xq << endl;
+ // }
+ // pte();
+ int kind;
+ cin >> kind;
+ if (kind != 1 && kind != 2) {
+ cout << "error" << endl;
+ exit(0);
+ }
+ // 输入分配方式,1是负担均匀,2是尽早学习
+ if (kind == 1) {
+ avgf();
+ } else if (kind == 2) {
+ // 本来就是今早分配的,无需更改
+ } else {
+ cout << "error" << endl;
+ exit(0);
+ }
+ // 输出最终结果
+ pte();
+ return 0;
+}
+
+平均负载
+6 10
+12
+C01 C02 C03 C04 C05 C06 C07 C08 C09 C10 C11 C12
+2 0
+3 1 C01
+4 2 C01 C02
+3 1 C01
+2 2 C03 C04
+3 1 C11
+4 2 C03 C05
+4 2 C03 C06
+7 0
+5 1 C09
+2 1 C09
+3 3 C01 C09 C10
+1
+
+学期 1 学分 9 课程数 2 课程:C01 C09
+学期 2 学分 8 课程数 2 课程:C02 C11
+学期 3 学分 9 课程数 2 课程:C03 C04
+学期 4 学分 8 课程数 2 课程:C05 C10
+学期 5 学分 8 课程数 2 课程:C12 C06
+学期 6 学分 0 课程数 2 课程:C08 C07
+
+尽早学完
+6 10
+12
+C01 C02 C03 C04 C05 C06 C07 C08 C09 C10 C11 C12
+2 0
+3 1 C01
+4 2 C01 C02
+3 1 C01
+2 2 C03 C04
+3 1 C11
+4 2 C03 C05
+4 2 C03 C06
+7 0
+5 1 C09
+2 1 C09
+3 3 C01 C09 C10
+2
+
+学期 1 学分 9 课程数 2 课程:C01 C09
+学期 2 学分 8 课程数 3 课程:C02 C04 C11
+学期 3 学分 9 课程数 2 课程:C10 C03
+学期 4 学分 8 课程数 3 课程:C12 C06 C05
+学期 5 学分 8 课程数 2 课程:C08 C07
+
+分别采用二叉链表和顺序表作存储结构,实现对二叉排序树与平衡二叉树的操作。
+用二叉链表作存储结构实现二叉排序树。
+用顺序表(一维数组)作存储结构----静态链表
+用二叉链表作存储结构实平衡的二叉排序树。
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct Tree {
+ int val;
+ struct Tree *l, *r;
+ struct Tree *parent;
+} Tree;
+
+int n;
+int m;
+
+void makeTree(Tree *root, int val) {
+ if (val < root->val) {
+ if (root->l == NULL) {
+ root->l = (Tree *)malloc(sizeof(Tree));
+ root->l->val = val;
+ root->l->l = NULL;
+ root->l->r = NULL;
+ root->l->parent = root;
+ } else {
+ makeTree(root->l, val);
+ }
+ } else {
+ if (root->r == NULL) {
+ root->r = (Tree *)malloc(sizeof(Tree));
+ root->r->val = val;
+ root->r->l = NULL;
+ root->r->r = NULL;
+ root->r->parent = root;
+ } else {
+ makeTree(root->r, val);
+ }
+ }
+}
+
+// 中序遍历
+void inOrder(Tree *root) {
+ if (root == NULL)
+ return;
+ inOrder(root->l);
+ printf("%d ", root->val);
+ inOrder(root->r);
+}
+
+// 二叉排序树T查找成功的平均查找长度
+double ASL(Tree *root, int level) {
+ if (root == NULL)
+ return 0;
+ return level + ASL(root->l, level + 1) + ASL(root->r, level + 1);
+}
+
+// 找到二叉树中值为val的节点并删除
+void delNode(Tree *root, int val) {
+ if (root == NULL)
+ return;
+ if (root->val == val) {
+ if (root->l == NULL && root->r == NULL) {
+ if (root->parent->l == root) {
+ root->parent->l = NULL;
+ } else {
+ root->parent->r = NULL;
+ }
+ free(root);
+ } else if (root->l == NULL) {
+ if (root->parent->l == root) {
+ root->parent->l = root->r;
+ } else {
+ root->parent->r = root->r;
+ }
+ free(root);
+ } else if (root->r == NULL) {
+ if (root->parent->l == root) {
+ root->parent->l = root->l;
+ } else {
+ root->parent->r = root->l;
+ }
+ free(root);
+ } else {
+ Tree *p = root->r;
+ while (p->l != NULL) {
+ p = p->l;
+ }
+ root->val = p->val;
+ delNode(p, p->val);
+ }
+ } else if (root->val > val) {
+ delNode(root->l, val);
+ } else {
+ delNode(root->r, val);
+ }
+}
+
+void pt(Tree *root) {
+ printf("inOrder:\n");
+ inOrder(root);
+ printf("\n");
+ printf("ASL: %lf\n", ASL(root, 1) / n);
+ printf("\n");
+}
+
+int main() {
+ freopen("data.in", "r", stdin);
+ scanf("%d", &n);
+ Tree *root = (Tree *)malloc(sizeof(Tree));
+ root->parent = NULL;
+ for (int i = 0; i < n; i++) {
+ int val;
+ scanf("%d", &val);
+ if (i == 0) {
+ root->val = val;
+ root->l = NULL;
+ root->r = NULL;
+ } else {
+ makeTree(root, val);
+ }
+ }
+ pt(root);
+
+ scanf("%d", &m);
+ for (int i = 0; i < m; i++) {
+ int x;
+ scanf("%d", &x);
+ delNode(root, x);
+ pt(root);
+ }
+ return 0;
+}
+
+10
+2 5 10 8 7 9 4 6 1 3
+3
+2
+5
+9
+
+inOrder:
+1 2 3 4 5 6 7 8 9 10
+ASL: 3.500000
+
+inOrder:
+1 3 4 5 6 7 8 9 10
+ASL: 3.100000
+
+inOrder:
+1 3 4 6 7 8 9 10
+ASL: 2.500000
+
+inOrder:
+1 3 4 6 7 8 10
+ASL: 2.000000
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int n;
+int m;
+// 二叉排序树,根节点为 1,左子树为 2 * i,右子树为 2 * i + 1
+int tree[1000];
+
+void makeTree(int val) {
+ int r = 1;
+ while (1) {
+ if (val < tree[r]) {
+ if (tree[2 * r] == 0) {
+ // printf("r: %d, val: %d\n", 2 * r, val);
+ tree[2 * r] = val;
+ break;
+ } else {
+ r = 2 * r;
+ }
+ } else {
+ if (tree[2 * r + 1] == 0) {
+ // printf("r: %d, val: %d\n", 2 * r + 1, val);
+ tree[2 * r + 1] = val;
+ break;
+ } else {
+ r = 2 * r + 1;
+ }
+ }
+ }
+}
+
+// 中序遍历
+void inOrder(int root) {
+ if (tree[2 * root] != 0)
+ inOrder(2 * root);
+ printf("%d ", tree[root]);
+ if (tree[2 * root + 1] != 0)
+ inOrder(2 * root + 1);
+}
+
+// 二叉排序树T查找成功的平均查找长度
+double ASL(int root, int level) {
+ if (tree[root] == 0)
+ return 0;
+ return level + ASL(2 * root, level + 1) + ASL(2 * root + 1, level + 1);
+}
+
+// 找到二叉树中值为val的节点并删除
+void delNode(int root, int x) {
+ if (tree[root] == 0)
+ return;
+ if (tree[root] == x) {
+ if (tree[2 * root] == 0 && tree[2 * root + 1] == 0) {
+ tree[root] = 0;
+ } else if (tree[2 * root] != 0 && tree[2 * root + 1] == 0) {
+ tree[root] = tree[2 * root];
+ tree[2 * root] = 0;
+ } else if (tree[2 * root] == 0 && tree[2 * root + 1] != 0) {
+ tree[root] = tree[2 * root + 1];
+ tree[2 * root + 1] = 0;
+ } else {
+ int r = 2 * root + 1;
+ while (tree[2 * r] != 0) {
+ r = 2 * r;
+ }
+ tree[root] = tree[r];
+ tree[r] = 0;
+ }
+ } else if (tree[root] > x) {
+ delNode(2 * root, x);
+ } else {
+ delNode(2 * root + 1, x);
+ }
+}
+
+void pt() {
+ printf("inOrder:\n");
+ inOrder(1);
+ printf("\n");
+ printf("ASL: %lf\n", ASL(1, 1) / n);
+ printf("\n");
+}
+
+int main() {
+ freopen("data.in", "r", stdin);
+ scanf("%d", &n);
+ for (int i = 1; i <= n; i++) {
+ int val;
+ scanf("%d", &val);
+ if (i == 1) {
+ tree[1] = val;
+ } else {
+ makeTree(val);
+ }
+ }
+ pt();
+
+ scanf("%d", &m);
+ for (int i = 0; i < m; i++) {
+ int x;
+ scanf("%d", &x);
+ delNode(1, x);
+ pt();
+ }
+ return 0;
+}
+
+10 +2 5 10 8 7 9 4 6 1 3 +3 +2 +5 +9
+inOrder:
+1 2 3 4 5 6 7 8 9 10
+ASL: 3.500000
+
+inOrder:
+1 3 4 5 6 7 8 9 10
+ASL: 3.100000
+
+inOrder:
+1 3 4 6 7 8 9 10
+ASL: 2.500000
+
+inOrder:
+1 3 4 6 7 8 10
+ASL: 2.000000
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct Tree {
+ int val;
+ struct Tree *l, *r;
+ struct Tree *parent;
+ int height;
+ int balance;
+} Tree;
+
+int n;
+int m;
+
+// 获取节点高度
+int getHeight(Tree *root) {
+ if (root == NULL)
+ return 0;
+ return root->height;
+}
+
+// 更新节点高度和平衡因子
+void updateHeight(Tree *root) {
+ if (root == NULL)
+ return;
+ int l = getHeight(root->l);
+ int r = getHeight(root->r);
+ root->height = (l > r ? l : r) + 1;
+ root->balance = l - r;
+}
+
+// 左旋操作
+Tree *leftRotate(Tree *root) {
+ Tree *newRoot = root->r;
+ root->r = newRoot->l;
+ if (newRoot->l != NULL)
+ newRoot->l->parent = root;
+ newRoot->l = root;
+ newRoot->parent = root->parent;
+ root->parent = newRoot;
+ updateHeight(root);
+ updateHeight(newRoot);
+ return newRoot;
+}
+
+// 右旋操作
+Tree *rightRotate(Tree *root) {
+ Tree *newRoot = root->l;
+ root->l = newRoot->r;
+ if (newRoot->r != NULL)
+ newRoot->r->parent = root;
+ newRoot->r = root;
+ newRoot->parent = root->parent;
+ root->parent = newRoot;
+ updateHeight(root);
+ updateHeight(newRoot);
+ return newRoot;
+}
+
+// 左右旋操作
+Tree *leftRightRotate(Tree *root) {
+ root->l = leftRotate(root->l);
+ return rightRotate(root);
+}
+
+// 右左旋操作
+Tree *rightLeftRotate(Tree *root) {
+ root->r = rightRotate(root->r);
+ return leftRotate(root);
+}
+
+// 插入节点
+Tree *insertNode(Tree *root, int val) {
+ if (root == NULL) {
+ Tree *tmp = (Tree *)malloc(sizeof(Tree));
+ tmp->val = val;
+ tmp->l = NULL;
+ tmp->r = NULL;
+ tmp->parent = NULL;
+ tmp->height = 1;
+ tmp->balance = 0;
+ return tmp;
+ }
+
+ if (val < root->val) {
+ root->l = insertNode(root->l, val);
+ root->l->parent = root;
+ } else {
+ root->r = insertNode(root->r, val);
+ root->r->parent = root;
+ }
+
+ updateHeight(root);
+ if (root->balance > 1) {
+ if (val < root->l->val) {
+ return rightRotate(root);
+ } else {
+ return leftRightRotate(root);
+ }
+ } else if (root->balance < -1) {
+ if (val > root->r->val) {
+ return leftRotate(root);
+ } else {
+ return rightLeftRotate(root);
+ }
+ }
+
+ return root;
+}
+
+// 删除节点
+Tree *deleteNode(Tree *root, int val) {
+ if (root == NULL)
+ return NULL;
+
+ if (val < root->val) {
+ root->l = deleteNode(root->l, val);
+ } else if (val > root->val) {
+ root->r = deleteNode(root->r, val);
+ } else {
+ if (root->l == NULL && root->r == NULL) {
+ free(root);
+ return NULL;
+ } else if (root->l == NULL) {
+ Tree *temp = root->r;
+ free(root);
+ return temp;
+ } else if (root->r == NULL) {
+ Tree *temp = root->l;
+ free(root);
+ return temp;
+ } else {
+ Tree *minNode = root->r;
+ while (minNode->l != NULL)
+ minNode = minNode->l;
+ root->val = minNode->val;
+ root->r = deleteNode(root->r, minNode->val);
+ }
+ }
+
+ updateHeight(root);
+ if (root->balance > 1) {
+ if (getHeight(root->l->l) >= getHeight(root->l->r)) {
+ return rightRotate(root);
+ } else {
+ return leftRightRotate(root);
+ }
+ } else if (root->balance < -1) {
+ if (getHeight(root->r->r) >= getHeight(root->r->l)) {
+ return leftRotate(root);
+ } else {
+ return rightLeftRotate(root);
+ }
+ }
+
+ return root;
+}
+
+void makeTree(Tree *root, int val) {
+ if (val < root->val) {
+ if (root->l == NULL) {
+ root->l = (Tree *)malloc(sizeof(Tree));
+ root->l->val = val;
+ root->l->l = NULL;
+ root->l->r = NULL;
+ root->l->parent = root;
+ root->l->height = root->height + 1;
+ } else {
+ makeTree(root->l, val);
+ }
+ } else {
+ if (root->r == NULL) {
+ root->r = (Tree *)malloc(sizeof(Tree));
+ root->r->val = val;
+ root->r->l = NULL;
+ root->r->r = NULL;
+ root->r->parent = root;
+ root->r->height = root->height + 1;
+
+ } else {
+ makeTree(root->r, val);
+ }
+ }
+}
+
+// 中序遍历
+void inOrder(Tree *root) {
+ if (root == NULL)
+ return;
+ inOrder(root->l);
+ printf("%d ", root->val);
+ inOrder(root->r);
+}
+
+// 二叉排序树T查找成功的平均查找长度
+double ASL(Tree *root, int level) {
+ if (root == NULL)
+ return 0;
+ return level + ASL(root->l, level + 1) + ASL(root->r, level + 1);
+}
+
+// 找到二叉树中值为val的节点并删除
+void delNode(Tree *root, int val) {
+ if (root == NULL)
+ return;
+ if (root->val == val) {
+ if (root->l == NULL && root->r == NULL) {
+ if (root->parent->l == root) {
+ root->parent->l = NULL;
+ } else {
+ root->parent->r = NULL;
+ }
+ free(root);
+ } else if (root->l == NULL) {
+ if (root->parent->l == root) {
+ root->parent->l = root->r;
+ } else {
+ root->parent->r = root->r;
+ }
+ free(root);
+ } else if (root->r == NULL) {
+ if (root->parent->l == root) {
+ root->parent->l = root->l;
+ } else {
+ root->parent->r = root->l;
+ }
+ free(root);
+ } else {
+ Tree *p = root->r;
+ while (p->l != NULL) {
+ p = p->l;
+ }
+ root->val = p->val;
+ delNode(p, p->val);
+ }
+ } else if (root->val > val) {
+ delNode(root->l, val);
+ } else {
+ delNode(root->r, val);
+ }
+}
+
+void detail(Tree *root) {
+ if (root == NULL)
+ return;
+ printf("val: %d, height: %d, balance: %d, parent: %d\n", root->val,
+ root->height, root->balance,
+ root->parent == NULL ? -1 : root->parent->val);
+ detail(root->l);
+ detail(root->r);
+}
+
+void pt(Tree *root) {
+ printf("inOrder:\n");
+ inOrder(root);
+ printf("\n");
+ detail(root);
+ printf("ASL: %lf\n", ASL(root, 1) / n);
+ printf("\n");
+}
+
+// 打印二叉树
+void printTree(Tree *root, int level) {
+ if (root == NULL)
+ return;
+ printTree(root->r, level + 1);
+ for (int i = 0; i < level; i++)
+ printf(" ");
+ printf("%d\n", root->val);
+ printTree(root->l, level + 1);
+}
+
+
+int main() {
+ freopen("data.in", "r", stdin);
+ scanf("%d", &n);
+ Tree *root = NULL;
+ for (int i = 0; i < n; i++) {
+ int val;
+ scanf("%d", &val);
+ root = insertNode(root, val);
+ }
+ pt(root);
+
+ scanf("%d", &m);
+ for (int i = 0; i < m; i++) {
+ int x;
+ scanf("%d", &x);
+ root = deleteNode(root, x);
+ pt(root);
+ printTree(root, 0);
+ printf("----------------\n");
+ }
+
+ return 0;
+}
+
+10
+2 5 10 8 7 9 4 6 1 3
+3
+2
+5
+9
+
+二叉树图形输出为竖着
+1 2 3 4 5 6 7 8 9 10
+val: 5, height: 4, balance: 0, parent: -1
+val: 2, height: 3, balance: -1, parent: 5
+val: 1, height: 1, balance: 0, parent: 2
+val: 4, height: 2, balance: 1, parent: 2
+val: 3, height: 1, balance: 0, parent: 4
+val: 8, height: 3, balance: 0, parent: 5
+val: 7, height: 2, balance: 1, parent: 8
+val: 6, height: 1, balance: 0, parent: 7
+val: 10, height: 2, balance: 1, parent: 8
+val: 9, height: 1, balance: 0, parent: 10
+ASL: 2.900000
+
+inOrder:
+1 3 4 5 6 7 8 9 10
+val: 5, height: 4, balance: -1, parent: -1
+val: 3, height: 2, balance: 0, parent: 5
+val: 1, height: 1, balance: 0, parent: 3
+val: 4, height: 1, balance: 0, parent: 3
+val: 8, height: 3, balance: 0, parent: 5
+val: 7, height: 2, balance: 1, parent: 8
+val: 6, height: 1, balance: 0, parent: 7
+val: 10, height: 2, balance: 1, parent: 8
+val: 9, height: 1, balance: 0, parent: 10
+ASL: 2.500000
+
+ 10
+ 9
+ 8
+ 7
+ 6
+5
+ 4
+ 3
+ 1
+----------------
+inOrder:
+1 3 4 6 7 8 9 10
+val: 6, height: 4, balance: -1, parent: -1
+val: 3, height: 2, balance: 0, parent: 6
+val: 1, height: 1, balance: 0, parent: 3
+val: 4, height: 1, balance: 0, parent: 3
+val: 8, height: 3, balance: -1, parent: 6
+val: 7, height: 1, balance: 0, parent: 8
+val: 10, height: 2, balance: 1, parent: 8
+val: 9, height: 1, balance: 0, parent: 10
+ASL: 2.100000
+
+ 10
+ 9
+ 8
+ 7
+6
+ 4
+ 3
+ 1
+----------------
+inOrder:
+1 3 4 6 7 8 10
+val: 6, height: 3, balance: 0, parent: -1
+val: 3, height: 2, balance: 0, parent: 6
+val: 1, height: 1, balance: 0, parent: 3
+val: 4, height: 1, balance: 0, parent: 3
+val: 8, height: 2, balance: 0, parent: 6
+val: 7, height: 1, balance: 0, parent: 8
+val: 10, height: 1, balance: 0, parent: 8
+ASL: 1.700000
+
+ 10
+ 8
+ 7
+6
+ 4
+ 3
+ 1
+----------------
+
+录入、保存一个班级学生多门课程的成绩,并对成绩进行分析。
+input.dat
。input.dat
中的数据进行处理,要求具有如下功能:
+60-69
分人数、70-79
分人数、 80-89
分人数、90
分以上人数。#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ char *uid;
+ char *name;
+ int math, eng, cs;
+} Score;
+
+// 保存到文件
+void save_to_file(Score **scores, int n, char *file_name) {
+ FILE *fp = fopen(file_name, "w");
+ fprintf(fp, "%d\n", n);
+ for (int i = 0; i < n; i++) {
+ fprintf(fp, "%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ }
+ fclose(fp);
+}
+
+int main() {
+ Score *scores[105];
+ int n;
+ // 如果 score.dat 不存在,就从键盘输入
+ FILE *fp = fopen("score.dat", "r");
+ if (fp == NULL) {
+ printf("score.dat not found, please input:\n");
+ scanf("%d", &n);
+ fp = fopen("score.dat", "w");
+ fprintf(fp, "%d\n", n);
+ for (int i = 0; i < n; i++) {
+ scores[i] = (Score *)malloc(sizeof(Score));
+ char *uid = (char *)malloc(sizeof(char) * 105);
+ char *name = (char *)malloc(sizeof(char) * 105);
+ scanf("%s %s %d %d %d", uid, name, &scores[i]->math,
+ &scores[i]->eng, &scores[i]->cs);
+ scores[i]->uid = uid;
+ scores[i]->name = name;
+ fprintf(fp, "%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ }
+ fclose(fp);
+ } else {
+ // 从 score.dat 读取
+ fscanf(fp, "%d", &n);
+ for (int i = 0; i < n; i++) {
+ scores[i] = (Score *)malloc(sizeof(Score));
+ char *uid = (char *)malloc(sizeof(char) * 105);
+ char *name = (char *)malloc(sizeof(char) * 105);
+ fscanf(fp, "%s %s %d %d %d", uid, name, &scores[i]->math,
+ &scores[i]->eng, &scores[i]->cs);
+ scores[i]->uid = uid;
+ scores[i]->name = name;
+ }
+ fclose(fp);
+ }
+
+ printf("Total: %d\n", n);
+
+ printf("当前数据:\n");
+ // 输出所有人的信息
+ for (int i = 0; i < n; i++) {
+ printf("%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ }
+ printf("--------------------\n");
+
+ // 按照每个科目排序并输出对应的排名
+ printf("按照数学成绩排序:\n");
+ for (int i = 0; i < n; i++) {
+ int max = i;
+ for (int j = i + 1; j < n; j++) {
+ if (scores[j]->math > scores[max]->math) {
+ max = j;
+ }
+ }
+ Score *tmp = scores[i];
+ scores[i] = scores[max];
+ scores[max] = tmp;
+ printf("%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ }
+ save_to_file(scores, n, "math.dat");
+ printf("--------------------\n");
+
+ printf("按照英语成绩排序:\n");
+ for (int i = 0; i < n; i++) {
+ int max = i;
+ for (int j = i + 1; j < n; j++) {
+ if (scores[j]->eng > scores[max]->eng) {
+ max = j;
+ }
+ }
+ Score *tmp = scores[i];
+ scores[i] = scores[max];
+ scores[max] = tmp;
+ printf("%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ }
+ save_to_file(scores, n, "eng.dat");
+ printf("--------------------\n");
+
+ printf("按照计算机成绩排序:\n");
+ for (int i = 0; i < n; i++) {
+ int max = i;
+ for (int j = i + 1; j < n; j++) {
+ if (scores[j]->cs > scores[max]->cs) {
+ max = j;
+ }
+ }
+ Score *tmp = scores[i];
+ scores[i] = scores[max];
+ scores[max] = tmp;
+ printf("%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ }
+ save_to_file(scores, n, "cs.dat");
+ printf("--------------------\n");
+
+ // 计算平均分,按平均成绩排序,写到 average.dat
+ printf("平均分:\n");
+ FILE *fp_average = fopen("average.dat", "w");
+ fprintf(fp_average, "%d\n", n);
+ double avg_scores[105];
+ for (int i = 0; i < n; i++) {
+ avg_scores[i] =
+ (scores[i]->math + scores[i]->eng + scores[i]->cs) / 3.0;
+ }
+ // sort
+ for (int i = 0; i < n; i++) {
+ int max = i;
+ for (int j = i + 1; j < n; j++) {
+ if (avg_scores[j] > avg_scores[max]) {
+ max = j;
+ }
+ }
+ int tmp = avg_scores[i];
+ avg_scores[i] = avg_scores[max];
+ avg_scores[max] = tmp;
+ Score *tmp_score = scores[i];
+ scores[i] = scores[max];
+ scores[max] = tmp_score;
+ }
+ for (int i = 0; i < n; i++) {
+ printf("%s %s %d %d %d %.2f\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs,
+ avg_scores[i] * 1.0);
+ fprintf(fp_average, "%s %s %d %d %d %.2f\n", scores[i]->uid,
+ scores[i]->name, scores[i]->math, scores[i]->eng, scores[i]->cs,
+ avg_scores[i] * 1.0);
+ }
+ fclose(fp_average);
+ printf("--------------------\n");
+
+ // 求出各门课程的平均成绩、最高分、最低分、不及格人数、60-69分人数、70-79分人数、
+ // 80-89分人数、90分以上人数。
+ int math_sum = 0, eng_sum = 0, cs_sum = 0;
+ int math_max = 0, eng_max = 0, cs_max = 0;
+ int math_min = 100, eng_min = 100, cs_min = 100;
+ int math_fail = 0, eng_fail = 0, cs_fail = 0;
+ int math_60_69 = 0, eng_60_69 = 0, cs_60_69 = 0;
+ int math_70_79 = 0, eng_70_79 = 0, cs_70_79 = 0;
+ int math_80_89 = 0, eng_80_89 = 0, cs_80_89 = 0;
+ int math_90 = 0, eng_90 = 0, cs_90 = 0;
+ for (int i = 0; i < n; i++) {
+ math_sum += scores[i]->math;
+ eng_sum += scores[i]->eng;
+ cs_sum += scores[i]->cs;
+ if (scores[i]->math > math_max) {
+ math_max = scores[i]->math;
+ }
+ if (scores[i]->eng > eng_max) {
+ eng_max = scores[i]->eng;
+ }
+ if (scores[i]->cs > cs_max) {
+ cs_max = scores[i]->cs;
+ }
+ if (scores[i]->math < math_min) {
+ math_min = scores[i]->math;
+ }
+ if (scores[i]->eng < eng_min) {
+ eng_min = scores[i]->eng;
+ }
+ if (scores[i]->cs < cs_min) {
+ cs_min = scores[i]->cs;
+ }
+ if (scores[i]->math < 60) {
+ math_fail++;
+ }
+ if (scores[i]->eng < 60) {
+ eng_fail++;
+ }
+ if (scores[i]->cs < 60) {
+ cs_fail++;
+ }
+ if (scores[i]->math >= 60 && scores[i]->math <= 69) {
+ math_60_69++;
+ }
+ if (scores[i]->eng >= 60 && scores[i]->eng <= 69) {
+ eng_60_69++;
+ }
+ if (scores[i]->cs >= 60 && scores[i]->cs <= 69) {
+ cs_60_69++;
+ }
+ if (scores[i]->math >= 70 && scores[i]->math <= 79) {
+ math_70_79++;
+ }
+ if (scores[i]->eng >= 70 && scores[i]->eng <= 79) {
+ eng_70_79++;
+ }
+ if (scores[i]->cs >= 70 && scores[i]->cs <= 79) {
+ cs_70_79++;
+ }
+ if (scores[i]->math >= 80 && scores[i]->math <= 89) {
+ math_80_89++;
+ }
+ if (scores[i]->eng >= 80 && scores[i]->eng <= 89) {
+ eng_80_89++;
+ }
+ if (scores[i]->cs >= 80 && scores[i]->cs <= 89) {
+ cs_80_89++;
+ }
+ if (scores[i]->math >= 90) {
+ math_90++;
+ }
+ if (scores[i]->eng >= 90) {
+ eng_90++;
+ }
+ if (scores[i]->cs >= 90) {
+ cs_90++;
+ }
+ }
+ printf("数学:\n平均分:%.2f 最高分:%d 最低分:%d 不及格人数:%d "
+ "60-69分人数:%d "
+ "70-79分人数:%d 80-89分人数:%d 90分以上人数:%d\n",
+ math_sum * 1.0 / n, math_max, math_min, math_fail, math_60_69,
+ math_70_79, math_80_89, math_90);
+ printf("英语:\n平均分:%.2f 最高分:%d 最低分:%d 不及格人数:%d "
+ "60-69分人数:%d "
+ "70-79分人数:%d 80-89分人数:%d 90分以上人数:%d\n",
+ eng_sum * 1.0 / n, eng_max, eng_min, eng_fail, eng_60_69, eng_70_79,
+ eng_80_89, eng_90);
+ printf("计算机:\n平均分:%.2f 最高分:%d 最低分:%d 不及格人数:%d "
+ "60-69分人数:%d "
+ "70-79分人数:%d 80-89分人数:%d 90分以上人数:%d\n",
+ cs_sum * 1.0 / n, cs_max, cs_min, cs_fail, cs_60_69, cs_70_79,
+ cs_80_89, cs_90);
+
+ // 根据姓名或学号查询某人的各门成绩,重名情况也能处理。
+ while (1) {
+ printf("请输入学号或姓名:\n");
+ char *query = (char *)malloc(sizeof(char) * 105);
+ scanf("%s", query);
+ int found = 0;
+ for (int i = 0; i < n; i++) {
+ if (strcmp(scores[i]->uid, query) == 0 ||
+ strcmp(scores[i]->name, query) == 0) {
+ printf("%s %s %d %d %d\n", scores[i]->uid, scores[i]->name,
+ scores[i]->math, scores[i]->eng, scores[i]->cs);
+ found = 1;
+ }
+ }
+ if (!found) {
+ printf("未找到\n");
+ }
+ }
+ return 0;
+}
+
+7
+001 L1 78 77 90
+002 L2 89 67 88
+003 L3 56 66 78
+004 L4 89 86 85
+005 L5 67 88 76
+006 L6 45 54 67
+007 L6 78 76 70
+
+Total: 7
+当前数据:
+001 L1 78 77 90
+002 L2 89 67 88
+003 L3 56 66 78
+004 L4 89 86 85
+005 L5 67 88 76
+006 L6 45 54 67
+007 L6 78 76 70
+--------------------
+按照数学成绩排序:
+002 L2 89 67 88
+004 L4 89 86 85
+001 L1 78 77 90
+007 L6 78 76 70
+005 L5 67 88 76
+003 L3 56 66 78
+006 L6 45 54 67
+--------------------
+按照英语成绩排序:
+005 L5 67 88 76
+004 L4 89 86 85
+001 L1 78 77 90
+007 L6 78 76 70
+002 L2 89 67 88
+003 L3 56 66 78
+006 L6 45 54 67
+--------------------
+按照计算机成绩排序:
+001 L1 78 77 90
+002 L2 89 67 88
+004 L4 89 86 85
+003 L3 56 66 78
+005 L5 67 88 76
+007 L6 78 76 70
+006 L6 45 54 67
+--------------------
+平均分:
+004 L4 89 86 85 86.67
+002 L2 89 67 88 81.00
+001 L1 78 77 90 81.00
+005 L5 67 88 76 77.00
+007 L6 78 76 70 74.67
+003 L3 56 66 78 66.00
+006 L6 45 54 67 55.00
+--------------------
+数学:
+平均分:71.71 最高分:89 最低分:45 不及格人数:2 60-69分人数:1 70-79分人数:2 80-89分人数:2 90分以上人数:0
+英语:
+平均分:73.43 最高分:88 最低分:54 不及格人数:1 60-69分人数:2 70-79分人数:2 80-89分人数:2 90分以上人数:0
+计算机:
+平均分:79.14 最高分:90 最低分:67 不及格人数:0 60-69分人数:1 70-79分人数:3 80-89分人数:2 90分以上人数:1
+请输入学号或姓名:
+L1
+001 L1 78 77 90
+请输入学号或姓名:
+L2
+002 L2 89 67 88
+请输入学号或姓名:
+L6
+007 L6 78 76 70
+006 L6 45 54 67
+> EOF <
+
+这是一个一元稀疏多项式的简单计算器,需要设计一种数据结构来存储多项式,并实现多项式的输入、输出、加法、减法和计算多项式在某个点的值的功能。
+采用带表头结点的单链表来存储多项式。链表的每个节点表示多项式的一项,节点包含两个成员变量:系数和指数。
+x
的指数次方,并累加到结果中。直接模拟
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct Node {
+ int c, e;
+ struct Node *next;
+} Node;
+
+typedef struct List {
+ Node head;
+ int len;
+} List;
+
+// 初始化链表
+List *init_list() {
+ List *l = (List *)malloc(sizeof(List));
+ l->head.next = NULL;
+ l->len = 0;
+ return l;
+}
+
+// 降序插入
+void insert(List *l, int c, int e) {
+ Node *p = &(l->head);
+ while (p->next && p->next->e > e) {
+ p = p->next;
+ }
+ if (p->next && p->next->e == e) {
+ p->next->c += c;
+ if (p->next->c == 0) {
+ Node *q = p->next;
+ p->next = q->next;
+ free(q);
+ l->len--;
+ }
+ } else {
+ Node *q = (Node *)malloc(sizeof(Node));
+ q->c = c, q->e = e;
+ q->next = p->next;
+ p->next = q;
+ l->len++;
+ }
+}
+
+// 只输出
+void output(List *l) {
+ Node *p = l->head.next;
+ printf("%d,", l->len);
+ while (p) {
+ printf("%d,%d", p->c, p->e);
+ p = p->next;
+ if (p)
+ printf(",");
+ }
+ printf("\n");
+}
+
+// 只输出
+void plus(List *l1, List *l2) {
+ Node *p1 = l1->head.next, *p2 = l2->head.next;
+ while (p1 && p2) {
+ if (p1->e > p2->e) {
+ printf("%d,%d,", p1->c, p1->e);
+ p1 = p1->next;
+ } else if (p1->e < p2->e) {
+ printf("%d,%d,", p2->c, p2->e);
+ p2 = p2->next;
+ } else {
+ printf("%d,%d,", p1->c + p2->c, p1->e);
+ p1 = p1->next;
+ p2 = p2->next;
+ }
+ }
+ while (p1) {
+ printf("%d,%d,", p1->c, p1->e);
+ p1 = p1->next;
+ }
+ while (p2) {
+ printf("%d,%d,", p2->c, p2->e);
+ p2 = p2->next;
+ }
+ printf("\n");
+}
+
+// 只输出
+void minus(List *l1, List *l2) {
+ Node *p1 = l1->head.next, *p2 = l2->head.next;
+ while (p1 && p2) {
+ if (p1->e > p2->e) {
+ printf("%d,%d,", p1->c, p1->e);
+ p1 = p1->next;
+ } else if (p1->e < p2->e) {
+ printf("%d,%d,", -p2->c, p2->e);
+ p2 = p2->next;
+ } else {
+ printf("%d,%d,", p1->c - p2->c, p1->e);
+ p1 = p1->next;
+ p2 = p2->next;
+ }
+ }
+ while (p1) {
+ printf("%d,%d,", p1->c, p1->e);
+ p1 = p1->next;
+ }
+ while (p2) {
+ printf("%d,%d,", -p2->c, p2->e);
+ p2 = p2->next;
+ }
+ printf("\n");
+}
+
+int calc(List *l, int x) {
+ int sum = 0;
+ Node *p = l->head.next;
+ while (p) {
+ sum += p->c * pow(x, p->e);
+ p = p->next;
+ }
+ return sum;
+}
+
+int main() {
+ // freopen("data.in", "r", stdin);
+ List *l = init_list();
+ List *l2 = init_list();
+ int n1, n2, c, e;
+ scanf("%d", &n1);
+ for (int i = 0; i < n1; i++) {
+ scanf("%d%d", &c, &e);
+ insert(l, c, e);
+ }
+ scanf("%d", &n2);
+ for (int i = 0; i < n2; i++) {
+ scanf("%d%d", &c, &e);
+ insert(l2, c, e);
+ }
+ output(l);
+ output(l2);
+ plus(l, l2);
+ minus(l, l2);
+ while (1) {
+ printf("请输入x的值:");
+ scanf("%d", &c);
+ if (c == -1)
+ break;
+ printf("%d\n", calc(l, c));
+ }
+ return 0;
+}
+
+4
+1 2
+5 2
+3 4
+666 9
+2
+1 3
+2 4
+
+3,666,9,3,4,6,2
+2,2,4,1,3
+666,9,5,4,1,3,6,2,
+666,9,1,4,-1,3,6,2,
+请输入x的值:1
+675
+请输入x的值:2
+341064
+请输入x的值:3
+13109175
+
+迷宫实验是取自心理学的一个古典实验。在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒中设置了许多墙,对行进方向形成了多处阻挡。盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。对同一只老鼠重复进行上述实验,一直到老鼠从入口到出口,而不走错一步。老鼠经多次试验终于得到它学习走迷宫的路线。
+迷宫由m行n列的二维数组设置,0表示无障碍,1表示有障碍。设入口为(1,1),出口为(m,n),每次只能从一个无障碍单元移到周围四个方向上任一无障碍单元。编程实现对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 +算法输入:代表迷宫入口的坐标 +算法输出:穿过迷宫的结果。 算法要点:创建迷宫,试探法查找路。
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int m, n;
+int maze[105][105];
+
+// 存储当前路径
+char *path[10005];
+int path_len = 0;
+
+void dfs(int x, int y) {
+ if (x == m && y == n) {
+ // 找到出口
+ for (int i = 0; i < path_len; i++) {
+ printf("%s", path[i]);
+ if (i != path_len - 1) {
+ printf("->");
+ }
+ }
+ printf("\n");
+ return;
+ }
+ maze[x][y] = 1;
+ // 四个方向依次尝试
+ if (x + 1 <= m && maze[x + 1][y] == 0) {
+ path[path_len] = (char *)malloc(sizeof(char) * 105);
+ sprintf(path[path_len++], "(%d, %d)", x + 1, y);
+ dfs(x + 1, y);
+ path_len--;
+ }
+ if (y + 1 <= n && maze[x][y + 1] == 0) {
+ path[path_len] = (char *)malloc(sizeof(char) * 105);
+ sprintf(path[path_len++], "(%d, %d)", x, y + 1);
+ dfs(x, y + 1);
+ path_len--;
+ }
+ if (x - 1 >= 1 && maze[x - 1][y] == 0) {
+ path[path_len] = (char *)malloc(sizeof(char) * 105);
+ sprintf(path[path_len++], "(%d, %d)", x - 1, y);
+ dfs(x - 1, y);
+ path_len--;
+ }
+ if (y - 1 >= 1 && maze[x][y - 1] == 0) {
+ path[path_len] = (char *)malloc(sizeof(char) * 105);
+ sprintf(path[path_len++], "(%d, %d)", x, y - 1);
+ dfs(x, y - 1);
+ path_len--;
+ }
+}
+
+int main() {
+ freopen("data.in", "r", stdin);
+ scanf("%d%d", &m, &n);
+ for (int i = 1; i <= m; i++) {
+ for (int j = 1; j <= n; j++) {
+ scanf("%d", &maze[i][j]);
+ }
+ }
+ path[path_len] = (char *)malloc(sizeof(char) * 105);
+ strcpy(path[path_len++], "(1, 1)");
+ dfs(1, 1);
+
+ return 0;
+}
+
+7 6
+0 0 1 1 0 0
+1 0 0 0 0 0
+1 0 0 0 0 1
+1 0 0 0 0 1
+1 1 0 0 0 0
+1 1 1 1 0 0
+
+(1, 1)->(1, 2)->(2, 2)->(3, 2)->(4, 2)->(4, 3)->(5, 3)->(5, 4)->(5, 5)->(6, 5)->(7, 5)->(7, 6)
+(1, 1)->(1, 2)->(2, 2)->(3, 2)->(4, 2)->(4, 3)->(5, 3)->(5, 4)->(5, 5)->(6, 5)->(6, 6)->(7, 6)
+
+通过本学期的数据结构实验, 我对数据结构有了更深的理解, 也对C
语言有了更深的理解. 通过实验, 我学会了如何使用C
和C++
语言来实现各种数据结构, 也学会了如何使用各种数据结构来解决实际问题.
Qt
版本的电子表格等待制作中, 预计在假期尝试.
Luthics
的个人博客:https://www.luthics.com/