├── README.md ├── stair.cpp ├── matrix_transpose.cpp ├── palindrome.cpp ├── big_int_sort.cpp ├── symmetric_matrix.cpp ├── words_count.cpp ├── sort.cpp ├── A+B_2.cpp ├── octal.cpp ├── youngest3_staff.cpp ├── number_of_guards.cpp ├── grades_sort.cpp ├── link_list.cpp ├── matrix_max.cpp ├── odd_check.cpp ├── print_date.cpp ├── special_sort.cpp ├── longest_shortest_text.cpp ├── factorial.cpp ├── A+B.cpp ├── find_position.cpp ├── ip_address.cpp ├── bst_2.cpp ├── top2_numbers.cpp ├── string_link.cpp ├── bst.cpp ├── BT_traversal.cpp └── crossriver.cpp /README.md: -------------------------------------------------------------------------------- 1 | # HUST_cskaoyan 2 | 华中科技大学计算机考研复试上机历年真题题解 3 | 4 | 部分题解本地通过测试,提交测试(平台牛客网)后有样例不通过,而此样例可以在本地通过 5 | 6 | 2021.1.16更新: 7 | 8 | 这个仓库是我去年考研成绩出来之前准备基科计院复试创建的,最后一道农夫羊菜狼过河的问题较难留在最后。解决之前成绩出来了,很遗憾没有考上😂,这道题也因此搁置,投入到毕设和调剂的工作中。 9 | 10 | 一晃2020都过去了,没想到这些个naive的代码在大佬云集的GitHub上也有人给了star,因此昨晚花了点时间把最后一道题搞定,也算是善始善终了 11 | -------------------------------------------------------------------------------- /stair.cpp: -------------------------------------------------------------------------------- 1 | /*===================================== 2 | N阶楼梯上楼问题:一次可以走两阶或一阶,问有多 3 | 少种上楼方式。(要求采用非递归方式) 4 | ======================================*/ 5 | 6 | 7 | 8 | #include 9 | using namespace std; 10 | 11 | int main(){ 12 | long methods[90]; 13 | methods[0] = 1, methods[1] = 2; 14 | for(int i = 2; i < 90; i++){ 15 | methods[i] = methods[i - 2] + methods[i - 1]; 16 | } 17 | int N; 18 | while(cin>>N){ 19 | cout< 9 | using namespace std; 10 | int main() 11 | { 12 | int matrix[100][100], N; 13 | cin>>N; 14 | for(int i = 0; i < N; i++) 15 | { 16 | for(int j = 0; j < N; j++) 17 | cin>>matrix[i][j]; 18 | } 19 | for(int i = 0; i < N; i++) 20 | { 21 | for(int j = 0; j < N; j++) 22 | { 23 | cout< 9 | #include 10 | using namespace std; 11 | 12 | int main(){ 13 | string str; 14 | while(cin>>str){ 15 | bool flag = true; 16 | int n = str.length() - 1; 17 | for(int i = 0; i < n; i++){ 18 | if(str[i] != str[n - i]){ 19 | flag = false; 20 | break; 21 | } 22 | } 23 | if(flag) 24 | cout<<"Yes!"< 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | bool cmp(string a, string b){ 13 | if(a.length() != b.length()) 14 | return a.length() < b.length(); //a、b不等长时,短的更小 15 | else 16 | return a < b; 17 | } //比较函数 18 | 19 | int main(){ 20 | int N; 21 | string str[100]; 22 | while(cin>>N){ 23 | for(int i = 0; i < N; i++){ 24 | cin>>str[i]; 25 | } 26 | sort(str, str + N, cmp); //排序 27 | for(int i = 0; i < N; i++){ 28 | cout< 8 | using namespace std; 9 | 10 | int main(){ 11 | int matrix[100][100]; 12 | int N; 13 | bool flag = true; 14 | cin>>N; 15 | for(int i = 0; i < N; i++){ 16 | for(int j = 0; j < N; j++){ 17 | cin>>matrix[i][j]; 18 | } 19 | } 20 | for(int i = 0; i < N; i++){ 21 | for(int j = 0; j < N; j++){ 22 | if(matrix[i][j] != matrix[j][i]){ 23 | flag = false; 24 | break; 25 | } 26 | } 27 | } 28 | if(flag) 29 | cout<<"Yes!"; 30 | else 31 | cout<<"No!"; 32 | return 0; 33 | } -------------------------------------------------------------------------------- /words_count.cpp: -------------------------------------------------------------------------------- 1 | /*========================================== 2 | 编一个程序,读入用户输入的,以“.”结尾的一行文字, 3 | 统计一共有多少个单词,并分别输出每个单词含有多少个 4 | 字符。(凡是以一个或多个空格隔开的部分就为一个单词) 5 | ==========================================*/ 6 | 7 | 8 | 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | int main() 14 | { 15 | string str; 16 | getline(cin, str); 17 | int p = 0; //设置指针指示当前在字符串中的位置 18 | int len = 0; //记录单词长度 19 | while(str[p] != '\0') 20 | { 21 | if(str[p] == '.') //到达字符串末尾,输出最后一个单词长度 22 | cout< 8 | using namespace std; 9 | 10 | int main(){ 11 | int data[100] = {0}; 12 | int n; 13 | cin>>n; 14 | for(int i = 0; i < n; i++){ 15 | cin>>data[i]; 16 | } 17 | for(int i = 0; i < n; i++){ 18 | int flag = 0; //指示该趟排序中有无元素交换,0为未交换 19 | for(int j = 0; j < n - i - 1; j++){ 20 | if(data[j] > data[j + 1]){ 21 | int temp = data[j]; 22 | data[j] = data[j + 1], data[j + 1] = temp; 23 | flag = 1; //标记此趟排序已有元素交换 24 | } 25 | } 26 | if(flag == 0) 27 | break; 28 | } //冒泡排序 29 | for(int i = 0; i < n; i++){ 30 | cout< 10 | using namespace std; 11 | 12 | int convert(char num[]){ 13 | int sum = 0; 14 | int i = 0; 15 | bool flag = true; //默认为正数 16 | if(num[0] == '-'){ 17 | i++; 18 | flag = false; 19 | } //第一位为'-',为负数 20 | while(num[i]){ 21 | if(num[i] == ','){ 22 | i++; continue; 23 | } 24 | int n = num[i] - '0'; 25 | sum = sum * 10 + n; 26 | i++; 27 | } 28 | if(flag) 29 | return sum; 30 | else 31 | return -sum; 32 | } 33 | 34 | int main(){ 35 | char A[10], B[10]; 36 | cin >> A >> B; 37 | int a = convert(A); 38 | int b = convert(B); 39 | cout << a + b < 8 | #include 9 | using namespace std; 10 | 11 | int main(){ 12 | int num; 13 | stack S; 14 | while(cin>>num){ 15 | int quotient, remainder; 16 | quotient = num; 17 | while(quotient / 8 != 0){ 18 | remainder = quotient % 8, quotient /= 8; 19 | S.push(remainder); 20 | } 21 | S.push(quotient % 8); //注意到当num < 8时不进入循环,直接将num入栈;且当除到八进制数最高位时,quotient < 8,不 22 | while(!S.empty()){ //进入循环,此步骤可将最高位入栈 23 | int n = S.top(); 24 | cout< 2 | /*================================== 3 | 职工有职工号,姓名,年龄.输入n个职工的信 4 | 息,找出3个年龄最小的职工打印出来。 5 | 若有相同的关键字,则按照“年龄>工号>姓名” 6 | 且由小到大的顺序排序 7 | 职工号(整数),姓名(字符串,长度不超过10), 8 | 年龄(整数,1~100) 9 | ===================================*/ 10 | 11 | 12 | 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | struct Staff{ 18 | string name; 19 | int number, age; 20 | }; 21 | 22 | bool cmp(Staff a, Staff b){ 23 | if(a.age != b.age) 24 | return a.age < b.age; 25 | else if(a.number != b.number) 26 | return a.number < b.number; 27 | else 28 | return a.name < b.name; 29 | } 30 | 31 | int main(){ 32 | int N; 33 | Staff sta[30]; 34 | cin >> N; 35 | for(int i = 0; i < N; i++) 36 | cin >> sta[i].number >> sta[i].name >> sta[i].age; 37 | sort(sta, sta + N, cmp); 38 | for(int i = 0; i < 3; i++) 39 | cout << sta[i].number << ' ' << sta[i].name << ' ' << sta[i].age << endl; 40 | return 0; 41 | } -------------------------------------------------------------------------------- /number_of_guards.cpp: -------------------------------------------------------------------------------- 1 | /*========================================== 2 | 守形数是这样一种整数,它的平方的低位部分等于它本身。 3 | 比如25的平方是625,低位部分是25,因此25是一个守形 4 | 数。 编一个程序,判断N是否为守形数。 5 | ==========================================*/ 6 | 7 | 8 | 9 | #include 10 | using namespace std; 11 | 12 | bool isNum_of_guards(int n){ 13 | int exp = n * n; 14 | int mod = exp; 15 | while(true){ 16 | if(mod >= 1000 && mod < 10000){ 17 | mod = mod % 1000; 18 | if(mod == n) 19 | return 1; 20 | } 21 | else if(mod >= 100 && mod < 1000){ 22 | mod = mod % 100; 23 | if(mod == n) 24 | return 1; 25 | } 26 | else if(mod >= 10 && mod < 100){ 27 | mod = mod % 10; 28 | if(mod == n) 29 | return 1; 30 | } 31 | else 32 | return 0; 33 | } 34 | } 35 | 36 | int main(){ 37 | int num; 38 | cin>>num; 39 | if(isNum_of_guards(num)) 40 | cout<<"Yes!"; 41 | else 42 | cout<<"No!"; 43 | return 0; 44 | } -------------------------------------------------------------------------------- /grades_sort.cpp: -------------------------------------------------------------------------------- 1 | /*========================================= 2 | 有N个学生的数据,将学生数据按成绩从低到高排序,如 3 | 果成绩相同则按姓名字符的字典序由小到大排序,如果姓 4 | 名的字典序也相同则按照学生的年龄从小到大排序,并输 5 | 出N个学生排序后的信息。 6 | ==========================================*/ 7 | 8 | 9 | 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | struct Student{ 16 | //char name[100]; 17 | string name; 18 | int age, grade; 19 | }; 20 | 21 | bool cmp(Student a, Student b){ 22 | if(a.grade != b.grade) 23 | return a.grade < b.grade; 24 | else if(a.name != b.name) 25 | return a.name < b.name; 26 | else 27 | return a.age < b.age; 28 | } //两字符串比较时,string类型可直接比较,字符数组则需使用strcmp()函数比较 29 | 30 | int main(){ 31 | Student Stu[1000]; 32 | int N; 33 | cin >> N; 34 | for(int i = 0; i < N; i++){ 35 | cin >> Stu[i].name >> Stu[i].age >> Stu[i].grade; 36 | } 37 | sort(Stu, Stu + N, cmp); 38 | for(int i = 0; i < N; i++){ 39 | cout << Stu[i].name << ' ' << Stu[i].age << ' ' << Stu[i].grade << endl; 40 | } 41 | return 0; 42 | } -------------------------------------------------------------------------------- /link_list.cpp: -------------------------------------------------------------------------------- 1 | /*====================== 2 | 建立一个升序链表并遍历输出 3 | ======================*/ 4 | 5 | 6 | 7 | #include 8 | using namespace std; 9 | 10 | typedef struct LNode{ 11 | int num; 12 | LNode *next; 13 | }LNode, *LList; 14 | 15 | LList CreateLList(){ 16 | LNode *l = new LNode; 17 | l->num = 0; 18 | l->next = NULL; 19 | return l; 20 | } //创建一个空链表 21 | 22 | void Insert(LList L, int n){ 23 | LNode *p = L->next, *pre = L; //p、pre分别指示当前结点和前一个结点 24 | while(p){ 25 | if(n > p->num){ 26 | pre = p; 27 | p = p->next; 28 | } 29 | else break; 30 | } 31 | LNode *q = new LNode; 32 | q->num = n; 33 | pre->next = q, q->next = p; 34 | } 35 | 36 | void Print(LList L){ 37 | LNode *p = L->next; 38 | while(p){ 39 | cout<num<<' '; 40 | p = p->next; 41 | } 42 | } 43 | 44 | int main(){ 45 | int n, number; 46 | LList list = CreateLList(); 47 | cin>>n; 48 | for(int i = 0; i < n; i++){ 49 | cin>>number; 50 | Insert(list, number); 51 | } 52 | Print(list); 53 | delete list; 54 | return 0; 55 | } -------------------------------------------------------------------------------- /matrix_max.cpp: -------------------------------------------------------------------------------- 1 | /*==================================== 2 | 编写一个程序输入一个m*n的矩阵存储并输出,并 3 | 且求出每行的最大值和每行的总和。 要求把每行 4 | 总和放入每行最大值的位置,如果有多个最大值, 5 | 取下标值最小的那一个作为最大值。 最后将结果 6 | 矩阵输出。 7 | ====================================*/ 8 | 9 | 10 | 11 | #include 12 | using namespace std; 13 | 14 | int main(){ 15 | int matrix[100][100]; 16 | int row, col; 17 | cin >>row>>col; 18 | for(int i = 0; i < row; i++){ 19 | for(int j = 0; j < col; j++){ 20 | cin>>matrix[i][j]; 21 | } 22 | } 23 | int max, sum, pos; 24 | for(int i = 0; i < row; i++){ 25 | max = INT_MIN, sum = 0; 26 | for(int j = 0; j < col; j++){ 27 | sum += matrix[i][j]; 28 | if(matrix[i][j] > max){ 29 | max = matrix[i][j]; 30 | pos = j; 31 | } 32 | } 33 | matrix[i][pos] = sum; 34 | } 35 | for(int i = 0; i < row; i++){ 36 | for(int j = 0; j < col; j++){ 37 | cout< 13 | using namespace std; 14 | 15 | int bin[8]; //存储二进制数 16 | void PrintcheckedValue(char cha){ 17 | int deci = cha - '\0'; //将字符转化为十进制数 18 | int i, rem; 19 | int flag = 0; 20 | for(i = 7; i >= 0; i--){ 21 | rem = deci % 2, deci /= 2; 22 | bin[i] = rem; 23 | if(deci == 0) 24 | break; 25 | } //将字符对应的十进制数转化为二进制 26 | for(int j = 0; j < i; j++) 27 | bin[j] = 0; //剩余位填0 28 | for(int j = 0; j < 8; j++){ 29 | if(bin[j] == 1) 30 | flag++; 31 | } //统计“1”的数量 32 | if(flag % 2) //奇数个“1” 33 | bin[0] = 0; 34 | else 35 | bin[0] = 1; 36 | for(int j = 0; j < 8; j++) 37 | cout << bin[j]; 38 | cout << endl; 39 | } 40 | 41 | int main(){ 42 | char ch[100]; 43 | int i = 0; 44 | cin >> ch; 45 | while(ch[i]){ 46 | PrintcheckedValue(ch[i]); 47 | i++; 48 | } 49 | return 0; 50 | } -------------------------------------------------------------------------------- /print_date.cpp: -------------------------------------------------------------------------------- 1 | /*====================================== 2 | 给出年分m和一年中的第n天,算出第n天是几月几号 3 | 输出的月份和日期要求两位 4 | 例如: 5 | 输入“2000 3” 6 | 输出“2000-01-03” 7 | =======================================*/ 8 | 9 | 10 | 11 | #include 12 | using namespace std; 13 | 14 | int year[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 15 | int leap_year[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 16 | 17 | bool isLeapYear(int year){ 18 | if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) 19 | return true; 20 | else 21 | return false; 22 | } 23 | void specificPrint(int n){ 24 | if(n < 10) 25 | cout << 0 << n; 26 | else 27 | cout << n; 28 | } 29 | 30 | int main(){ 31 | int y, m, d; 32 | m = 0; 33 | cin >> y >> d; 34 | if(isLeapYear(y)){ 35 | while(d > leap_year[m]){ 36 | d -= leap_year[m]; 37 | m++; 38 | } 39 | } 40 | else{ 41 | while(d > year[m]){ 42 | d -= year[m]; 43 | m++; 44 | } 45 | } 46 | m++; 47 | cout << y << '-'; 48 | specificPrint(m); 49 | cout << '-'; 50 | specificPrint(d); 51 | cout << endl; 52 | return 0; 53 | } -------------------------------------------------------------------------------- /special_sort.cpp: -------------------------------------------------------------------------------- 1 | /*========================================== 2 | 输入一系列整数,将其中最大的数挑出(如果有多个,则挑 3 | 出一个即可),并将剩下的数进行排序,如果无剩余的数, 4 | 则输出-1。 5 | ==========================================*/ 6 | 7 | 8 | 9 | #include 10 | using namespace std; 11 | 12 | int main(){ 13 | int data[1000] = {0}; 14 | int n, max, pos; //max和pos分别表示最大值及其在数组中的位置 15 | max = INT_MIN; 16 | cin>>n; 17 | for(int i = 0; i < n; i++){ 18 | cin>>data[i]; 19 | if(data[i] > max){ 20 | max = data[i], pos = i; 21 | } 22 | } 23 | for(int i = pos; i < n - 1; i++){ 24 | data[i] = data[i + 1]; 25 | } //去除最大值,将其后的元素前移 26 | for(int i = 0; i < n - 1; i++){ 27 | int flag = 0; 28 | for(int j = 0; j < n - i - 2; j++){ 29 | if(data[j] > data[j + 1]){ 30 | int temp = data[j]; 31 | data[j] = data[j + 1], data[j + 1] = temp; 32 | flag = 1; 33 | } 34 | } 35 | if(flag ==0) 36 | break; 37 | } 38 | cout< 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | int main(){ 15 | string str; 16 | vector vec; //使用vector容器来存储输入的字符串 17 | while(getline(cin, str)){ //注意字符串中可能存在空格 18 | vec.push_back(str); 19 | } 20 | int n = vec.size(); 21 | int maxlen = 0, minlen = 1001; 22 | for(int i = 0; i < n; i++){ 23 | if(vec[i].length() > maxlen) 24 | maxlen = vec[i].length(); 25 | if(vec[i].length() < minlen) 26 | minlen = vec[i].length(); 27 | } //确定最大、最小字符串长度 28 | vector max, min; 29 | for(int i = 0; i < n; i++){ 30 | if(vec[i].length() == maxlen) 31 | max.push_back(i); 32 | if(vec[i].length() == minlen) 33 | min.push_back(i); 34 | } //统计最长和最短的字符串 35 | for(int i = 0; i < min.size(); i++){ 36 | int pos = min[i]; 37 | cout< 10 | using namespace std; 11 | 12 | long fractorial(int n){ 13 | long y = 1; 14 | for(int i = 1; i <= n; i++) 15 | y *= i; 16 | return y; 17 | } 18 | 19 | int main(){ 20 | int num; 21 | long y1 = 0, y2 = 0; 22 | cin>>num; 23 | for(int i = 1; i <= num; i += 2) 24 | y1 += fractorial(i); 25 | for(int i = 2; i <= num; i += 2) 26 | y2 += fractorial(i); 27 | cout< 37 | using namespace std; 38 | int main() 39 | { 40 | int n ,ans1, ans2, i, j; 41 | while (cin >> n) { 42 | ans1 = ans2 = 0, j = 1; 43 | for (i = 1; i <= n; ++i) { 44 | j *= i; //j用来保存当前数字i的阶乘 45 | if (i % 2) ans1 += j; //i为奇数,ans1加上i! 46 | else ans2 += j; //i为偶数,ans2加上i! 47 | } 48 | cout << ans1 << " " << ans2 << endl; 49 | } 50 | } 51 | 52 | */ -------------------------------------------------------------------------------- /A+B.cpp: -------------------------------------------------------------------------------- 1 | /*====================================== 2 | 实现一个加法器,使其能够输出a+b的值 3 | 输入包括两个数a和b,其中a和b的位数不超过1000位 4 | a、b以字符串形式输入 5 | ======================================*/ 6 | 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | char A_char[1000], B_char[1000]; 15 | int A_int[1000] = {0}, B_int[1000] = {0}, sum[1001]; 16 | 17 | int main(){ 18 | cin >> A_char >> B_char; 19 | int len1, len2; 20 | len1 = strlen(A_char), len2 = strlen(B_char); 21 | reverse(A_char, A_char + len1); 22 | reverse(B_char, B_char + len2); 23 | for(int i = 0; i < len1; i++) 24 | A_int[i] = A_char[i] - '0'; 25 | for(int i = 0; i < len2; i++) 26 | B_int[i] = B_char[i] - '0'; 27 | int c = 0; //进位位 28 | for(int i = 0; i <= len1 || i <= len2; i++){ //此处详解见末尾 29 | sum[i] = (A_int[i] + B_int[i] + c) % 10; //当前位的值 30 | c = (A_int[i] + B_int[i] + c) / 10; //当前为的进位值 31 | } 32 | int len = len1 > len2 ? len1 : len2; //得到最终和的长度 33 | for(int i = len; i >= 0; i--){ //逆序输出 34 | if(i == len && sum[i] == 0) //最高位为0不输出 35 | continue; 36 | cout << sum[i]; 37 | } 38 | cout << endl; 39 | return 0; 40 | } 41 | 42 | /*关于按位加法循环条件的说明: 43 | 这里循环条件中的<=与前面的初始化数组全为0一起保证能正常处理进位 44 | 例如若len1 < len2,len1 <= i <= len2时,A_int[i]实际不是 45 | 数A的有效位,但它们都为0,可与数B的有效位相加实现正常的进位,同 46 | 时也保证了最高位的进位 47 | */ -------------------------------------------------------------------------------- /find_position.cpp: -------------------------------------------------------------------------------- 1 | /*================================================================ 2 | 对给定的一个字符串,找出有重复的字符,并给出其位置 3 | 例如: 4 | 输入“abcaaAB12ab12” 5 | 输出“a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13” 6 | ================================================================*/ 7 | 8 | 9 | 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | int main(){ 15 | string str; 16 | while(cin>>str){ 17 | int len = str.length(); 18 | for(int i = 0; i < len - 1; i++){ //外循环,对当前字符(str[i])之后的字符进行逐个比较 19 | bool flag = false; //标记当前字符之后是否有相同字符 20 | if(str[i] == '*') 21 | continue; //当前字符为*,表示之前已经访问过并输出 22 | for(int j = i + 1; j < len; j++){ //内循环,遍历当前字符之后的每一个字符(str[j]) 23 | if(str[j] == str[i]){ 24 | if(!flag){ //两字符相同,flag为false,则先输出比较对象str[i] 25 | cout< 9 | #include 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | /*int n; 15 | cin>>n; 16 | int *sign = new int [n]; //动态数组sign用以存储每个ip地址的判断值 17 | for(int i = 0; i < n; i++) 18 | { 19 | string ip; 20 | cin>>ip; 21 | sign[i] = 1; //默认ip地址合法 22 | int sum = 0; //存储当前地址段的值 23 | int p = 0; //指针 24 | while(ip[p] != '\0') 25 | { 26 | if(ip[p] != '.') 27 | { 28 | sum = sum * 10 + (ip[p] - '0'); 29 | if(sum < 0 || sum > 255) 30 | sign[i] = 0; 31 | } 32 | else 33 | sum = 0; 34 | p++; 35 | } 36 | } 37 | for(int i = 0; i < n; i++) 38 | { 39 | if(sign[i] == 1) 40 | cout<<"Yes!"<>ip; 47 | int sum = 0; 48 | int p = 0; //指针 49 | while(ip[p] != '\0') 50 | { 51 | if(ip[p] != '.') 52 | { 53 | sum = sum * 10 + (ip[p] - '0'); 54 | if(sum < 0 || sum > 255) 55 | s = 0; 56 | } 57 | else 58 | sum = 0; 59 | p++; 60 | } 61 | if(s == 1) 62 | cout<<"Yes!"< 9 | using namespace std; 10 | 11 | typedef struct treeNode{ 12 | int num; 13 | treeNode *lchild, *rchild; 14 | }*BST; //不同于bst.cpp,此处采用链表结构 15 | void Insert(BST &T, int n){ 16 | if(T == NULL){ 17 | treeNode *t = new treeNode; 18 | t->num = n; 19 | t->lchild = t->rchild = NULL; 20 | T = t; 21 | return; 22 | } 23 | if(n == T->num){ 24 | return; 25 | } 26 | else if(n > T->num){ 27 | Insert(T->rchild, n); 28 | } 29 | else{ 30 | Insert(T->lchild, n); 31 | } 32 | } //递归插入结点 33 | BST CreateBST(int N){ 34 | BST T = NULL; 35 | int n; 36 | for(int i = 0; i < N; i++){ 37 | cin>>n; 38 | Insert(T, n); 39 | } 40 | return T; 41 | } 42 | void preOrder(BST T){ 43 | if(T == NULL){ 44 | return; 45 | } 46 | cout<num<<' '; 47 | preOrder(T->lchild); 48 | preOrder(T->rchild); 49 | } //前序遍历 50 | void inOrder(BST T){ 51 | if(T == NULL){ 52 | return; 53 | } 54 | inOrder(T->lchild); 55 | cout<num<<' '; 56 | inOrder(T->rchild); 57 | } //中序遍历 58 | void postOrder(BST T){ 59 | if(T == NULL){ 60 | return; 61 | } 62 | postOrder(T->lchild); 63 | postOrder(T->rchild); 64 | cout<num<<' '; 65 | } //后序遍历 66 | 67 | int main(){ 68 | int N; 69 | cin>>N; 70 | BST T = CreateBST(N); 71 | preOrder(T); 72 | cout< 22 | using namespace std; 23 | 24 | int main(){ 25 | int matrix[4][5]; 26 | for(int i = 0; i < 4; i++){ 27 | for(int j = 0; j < 5; j++){ 28 | cin >> matrix[i][j]; 29 | } 30 | } 31 | for(int i = 0; i < 5; i++){ 32 | int min = matrix[0][i], pos = 0; 33 | for(int j = 0; j < 4; j++){ 34 | if(matrix[j][i] < min){ 35 | min = matrix[j][i]; 36 | pos = j; 37 | } 38 | } //找出最小元素及其位置 39 | for(int k = pos; k < 4 - 1; k++) 40 | matrix[k][i] = matrix[k + 1][i]; //后移 41 | matrix[3][i] = min; 42 | min = matrix[0][i], pos = 0; //重置最小元素及其位置 43 | for(int l = 0; l < 3; l++){ 44 | if(matrix[l][i] < min){ 45 | min = matrix[l][i]; 46 | pos = l; 47 | } 48 | } //找出第二小元素及其位置 49 | for(int m = pos; m < 3 - 1; m++) 50 | matrix[m][i] = matrix[m + 1][i]; //后移 51 | matrix[2][i] = min; 52 | } 53 | for(int i = 0; i < 5; i++) 54 | cout << matrix[0][i] << ' '; 55 | cout << endl; 56 | for(int i = 0; i < 5; i++) 57 | cout << matrix[1][i] << ' '; 58 | cout << endl; 59 | return 0; 60 | } -------------------------------------------------------------------------------- /string_link.cpp: -------------------------------------------------------------------------------- 1 | /*================================== 2 | 不借用任何字符串库函数实现无冗余地接受两个 3 | 字符串,然后把它们无冗余的连接起来 4 | ==================================*/ 5 | 6 | 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | int main(){ 13 | string str1, str2; 14 | cin>>str1>>str2; 15 | string str; 16 | str = str1 + str2; 17 | cout< 10 | using namespace std; 11 | 12 | #define MAXSIZE 100 13 | typedef struct treeNode{ 14 | int data; 15 | int lchild, rchild, father; 16 | }BST; 17 | int pos = 0; //插入点指针,若插入结点,其在整个结构数组中的位置为pos 18 | void Initi(BST T[]){ 19 | for(int i = 0; i < MAXSIZE; i++){ 20 | T[i].data = 0; 21 | T[i].lchild = T[i].rchild = T[i].father = -1; 22 | } 23 | } //初始化结构数组 24 | void Insert(BST T[], int num){ 25 | if(T[0].data == 0){ 26 | T[0].data = num; 27 | } //空树,插入根结点 28 | else{ 29 | T[pos].data = num; 30 | T[pos].lchild = T[pos].rchild = -1; //取出结构数组中的一个元素并初始化 31 | int loc = 0; 32 | while(true){ 33 | if(num > T[loc].data){ 34 | if(T[loc].rchild != -1) 35 | loc = T[loc].rchild; 36 | else{ 37 | T[loc].rchild = pos, T[pos].father = loc; break; 38 | } 39 | } //向右到尽头并插入 40 | else{ 41 | if(T[loc].lchild != -1) 42 | loc = T[loc].lchild; 43 | else{ 44 | T[loc].lchild = pos, T[pos].father = loc; break; 45 | } 46 | } //向左到尽头并插入 47 | }//从根结点开始搜索插入位置 48 | } 49 | pos++; //完成插入,插入点后移 50 | } 51 | void createBST(int N, BST T[]){ 52 | int num; 53 | for(int i = 0; i < N; i++){ 54 | cin>>num; 55 | Insert(T, num); 56 | } 57 | } 58 | 59 | int main(){ 60 | BST tree[MAXSIZE]; 61 | Initi(tree); 62 | int N; 63 | cin>>N; 64 | createBST(N, tree); 65 | for(int i = 0; i < N; i++){ 66 | if(i == 0){ 67 | cout<<-1< 9 | using namespace std; 10 | 11 | typedef struct Node{ 12 | char cha; 13 | Node *lchild, *rchild; 14 | }*BT; //树结点,用于重建二叉树 15 | 16 | char preQue[26], inQue[26]; //前序、中序遍历序列 17 | 18 | BT reBuild(int preL, int preH, int inL, int inH){ //参数分别为需要重建的子树在前序、中序序列中的起止位置 19 | if(preL > preH || inL > inH) //子树不存在,到达尽头 20 | return NULL; 21 | Node* root = new Node; //新建当前子树根结点 22 | root->cha = preQue[preL]; //根结点为前序序列的第一个点 23 | int pos; 24 | for(pos = inL; pos <= inH; pos++){ 25 | if(root->cha == inQue[pos]) 26 | break; 27 | } //找到根结点在中序序列中的位置 28 | int len = pos - inL; //该根结点的左子树结点数 29 | root->lchild = reBuild(preL + 1, preL + len, inL, pos - 1); //重建左子树 30 | root->rchild = reBuild(preL + len + 1, preH, pos + 1, inH); //重建右子树 31 | return root; 32 | } 33 | void postOrder(BT T){ 34 | if(T->lchild) 35 | postOrder(T->lchild); 36 | if(T->rchild) 37 | postOrder(T->rchild); 38 | cout << T->cha; 39 | } 40 | 41 | int main(){ 42 | while(cin >> preQue >> inQue){ 43 | int l; 44 | for(l = 0; preQue[l] != '\0'; l++); 45 | BT T = reBuild(0, l, 0, l); 46 | postOrder(T); 47 | cout << endl; 48 | delete T; 49 | } 50 | return 0; 51 | } 52 | 53 | 54 | /* 55 | //直接得到后序遍历序列,不重建二叉树 56 | #include 57 | using namespace std; 58 | 59 | char preQue[26], inQue[26], postQue[26]; 60 | int p = 0; //插入点在后序序列中的位置 61 | 62 | void Post(int preL, int preH, int inL, int inH){ 63 | if(preL > preH || inL > inH) //到达尽头 64 | return; 65 | int pos; 66 | for(pos = inL; pos <= inH; pos++){ 67 | if(preQue[preL] == inQue[pos]) 68 | break; 69 | } //找到当前根结点在中序序列中的位置 70 | int len= pos - inL; 71 | Post(preL + 1, preL + len, inL, pos - 1); //递归处理左子树 72 | Post(preL + len + 1, preH, pos + 1, inH); //递归处理右子树 73 | postQue[p++] = preQue[preL]; //将当前根结点存入后序序列 74 | } 75 | 76 | int main(){ 77 | while(cin >> preQue >> inQue){ 78 | int l = 0; 79 | while(preQue[l++]); 80 | Post(0, l, 0, l); 81 | for(int i = 0; i <= l; i++) 82 | cout << postQue[i]; 83 | cout << endl; 84 | p = 0; //重置插入点位置供下一组输入用 85 | } 86 | return 0; 87 | } 88 | */ 89 | 90 | 91 | /*--------看到的一种使用STL实现的简洁方法 92 | #include 93 | #include 94 | using namespace std; 95 | 96 | void Post(string str1, string str2){ 97 | if(str1.length() == 0) 98 | return; 99 | int len = str2.find(str1[0]); //得到左子树结点数 100 | Post(str1.substr(1, len), str2.substr(0, len)); //递归处理左子树 101 | Post(str1.substr(1 + len), str2.substr(len + 1)); //递归处理右子树 102 | cout<> pre >> in){ 108 | Post(pre, in); 109 | } 110 | return 0; 111 | } 112 | */ -------------------------------------------------------------------------------- /crossriver.cpp: -------------------------------------------------------------------------------- 1 | /*=================================== 2 | 有一个农夫带一只羊、一筐菜和一只狼过河。如果 3 | 没有农夫看管,则狼要吃羊,羊要吃菜。但是船很 4 | 小,只够农夫带一样东西过河。问农夫该如何解此 5 | 难题? 6 | ===================================*/ 7 | 8 | /* 9 | 此题采用图的思想求解,要得到从初始状态结点到最终状态结点的无回路路径。 10 | 这个图具有所有的状态结点(包括合法与非法的),且是完全有向图,其边就代表过河操作; 11 | 采用深度优先搜索寻找路径,碰到不合法的状态转移则折返(不合法的状态或无法完成的操作) 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | //记录当前序列中出现过的状态,防止状态重复(死循环或非最优解) 20 | int state_in_que[16] = {0}; 21 | 22 | //共8种操作 23 | string action[8] = {"sheep_go", "sheep_come", "vegetable_go", "vegetable_come", 24 | "wolf_go", "wolf_come", "nothing_go", "nothing_come"}; 25 | 26 | //状态 27 | struct State 28 | { 29 | int farmer, sheep, veg, wolf; //0-未过河,1-过河 30 | State(int f, int s, int v, int w) : farmer(f), sheep(s), veg(v), wolf(w) {} 31 | /* 32 | 非法状态: 33 | 1000,1010,1001,0111,0101,0110 34 | 转换成整数: 35 | 8,10,9,7,5,6 36 | */ 37 | }; 38 | 39 | //将状态转换成整数 40 | int trans(State s) 41 | { 42 | return 8 * s.farmer + 4 * s.sheep + 2 * s.veg + s.wolf; 43 | } 44 | 45 | //接收当前状态及操作数,输出下一个状态 46 | State crossRiver(State now, int action) 47 | { 48 | int f, s, v, w; 49 | f = now.farmer, s = now.sheep, v = now.veg, w = now.wolf; //当前状态 50 | switch (action) 51 | { 52 | case 0: //sheep_go 53 | if (f == 0 && s == 0) //农夫与羊均未过河 54 | { 55 | State next(1, 1, v, w); 56 | return next; 57 | } 58 | else //农夫与羊不在一边,无法完成操作,则置next状态与当前now一致 59 | return now; 60 | break; 61 | case 1: //sheep_come 62 | if (f == 1 && s == 1) //农夫与羊均过河 63 | { 64 | State next(0, 0, v, w); 65 | return next; 66 | } 67 | else 68 | return now; 69 | break; 70 | case 2: //vegetable_go 71 | if (f == 0 && v == 0) //农夫与菜均未过河 72 | { 73 | State next(1, s, 1, w); 74 | return next; 75 | } 76 | else 77 | return now; 78 | break; 79 | case 3: //vegetable_come 80 | if (f == 1 && v == 1) //农夫与菜均过河 81 | { 82 | State next(0, s, 0, w); 83 | return next; 84 | } 85 | else 86 | return now; 87 | break; 88 | case 4: //wolf_go 89 | if (f == 0 && w == 0) //农夫与狼均未过河 90 | { 91 | State next(1, s, v, 1); 92 | return next; 93 | } 94 | else 95 | return now; 96 | break; 97 | case 5: //wolf_come 98 | if (f == 1 && w == 1) //农夫与狼均过河 99 | { 100 | State next(0, s, v, 0); 101 | return next; 102 | } 103 | else 104 | return now; 105 | break; 106 | case 6: //nothing_go 107 | if (f == 0) //农夫未过河 108 | { 109 | State next(1, s, v, w); 110 | return next; 111 | } 112 | else 113 | return now; 114 | break; 115 | case 7: //nothing_come 116 | if (f == 1) //农夫过河 117 | { 118 | State next(0, s, v, w); 119 | return next; 120 | } 121 | else 122 | return now; 123 | break; 124 | default: 125 | return now; 126 | break; 127 | } 128 | } 129 | 130 | //判断该次操作是否合法 131 | bool isValid(State now, State next) 132 | { 133 | int idx = trans(next); 134 | if (idx == trans(now)) //前后状态一样,非法 135 | return false; 136 | else if (idx == 5 || idx == 6 || idx == 7 || idx == 8 || idx == 9 || idx == 10) //非法状态 137 | return false; 138 | else if (state_in_que[idx] == 1) //之前已经出现过该状态,非法 139 | return false; 140 | else 141 | return true; 142 | } 143 | 144 | //判断是否为最终状态 145 | bool isFinished(State s) 146 | { 147 | if (trans(s) == 15) //最终状态1111 148 | return true; 149 | else 150 | return false; 151 | } 152 | 153 | int main() 154 | { 155 | State now(0, 0, 0, 0); //状态初始化 156 | vector stateQue; //状态序列 157 | vector nextAction; //操作指示,指示DFS过程中处于状态序列中对应位置的状态时当前应该进行的操作 158 | vector actionQue; //操作序列 159 | stateQue.push_back(now); //初始状态入列 160 | nextAction.push_back(0); //初始状态从0号操作开始 161 | while (!isFinished(now)) //序列最后一个状态不是最终状态,循环 162 | { 163 | now = stateQue[stateQue.size() - 1]; //获取当前状态 164 | state_in_que[trans(now)] = 1; //标记此状态已经历过 165 | int idx = nextAction[nextAction.size() - 1]; //获取当前应该执行的操作 166 | if (idx == 8) //当前状态可行的操作已遍历完却未解决问题,回溯 167 | { 168 | stateQue.pop_back(); //当前状态出列 169 | nextAction.pop_back(); //操作指示出列 170 | actionQue.pop_back(); //获得当前状态的操作出列 171 | state_in_que[trans(now)] = 0; //取消该状态的标记 172 | continue; 173 | } 174 | for (int i = idx; i < 8; i++) //从当前应该执行的操作开始向后寻找合法的操作 175 | { 176 | State next = crossRiver(now, i); 177 | if (!isValid(now, next)) //非法操作,跳过并尝试下一个操作 178 | { 179 | nextAction[nextAction.size() - 1] = i + 1; 180 | continue; 181 | } 182 | else 183 | { 184 | nextAction[nextAction.size() - 1] = i + 1; //下次返回此状态时从下一个操作开始 185 | actionQue.push_back(i); //当前操作入列 186 | stateQue.push_back(next); //下一个状态入列 187 | nextAction.push_back(0); //下一个状态为新状态,进行的操作应从0号开始 188 | break; 189 | } 190 | } 191 | } 192 | for (int i = 0; i < actionQue.size(); i++) 193 | cout << action[actionQue[i]] << endl; 194 | cout << "succeed" << endl; 195 | return 0; 196 | } 197 | 198 | /* 199 | 此题应该是有两个解,这里的代码得到一个解就马上输出了,不过平台的测试也没有很严格,输出一个正确解即可 200 | 网络上是找得到比这更好的能输出两个正确解的代码的 201 | 纯手打,技术有限可能不够简洁,网上有大佬的代码量更少,多多参考 202 | */ --------------------------------------------------------------------------------