数据结构作业2 | 字数总计: 2.5k | 阅读时长: 12分钟 | 阅读量: |
此作业为某大学数据结构作业2,答案为我当时所写,仅供学习和参考
问题 A: 统计回文子串 题目描述 现在给你一个字符串S,请你计算S中有多少连续子串是回文串。
输入 输入包含多组测试数据。每组输入是一个非空字符串,长度不超过5000。
输出 对于每组输入,输出回文子串的个数。
样例输入
样例输出
参考答案 查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> #include <bits/stdc++.h> using namespace std;int main () { string s; while (getline (cin, s)) { int ans=0 ; for (int i = 0 ; i < s.length (); ++i) { int j=i,k=i; while (j>=0 && k<s.length ()) { if (s[j]==s[k]) ++ans; else break ; --j; ++k; } } for (int i = 0 ; i < s.length ()-1 ; ++i) { int j=i,k=i+1 ; while (j>=0 && k<s.length ()) { if (s[j]==s[k]) ++ans; else break ; --j; ++k; } } cout << ans << endl; s.clear (); if (cin.peek () == '\n' ) break ; } return 0 ; }
问题 B: 构建矩阵 题目描述 现请你构建一个N*N的矩阵,第i行j列的元素为i与j的乘积。(i,j均从1开始)
输入 输入的第一行为一个正整数C,表示测试样例的个数。 然后是C行测试样例,每行为一个整数N(1<=N<=9),表示矩阵的行列数。
输出 对于每一组输入,输出构建的矩阵。
样例输入
样例输出 1 2 3 4 5 1 1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16
参考答案 查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> using namespace std;int main () { int n; cin >> n; while (n--) { int N; cin >> N; for (int i = 1 ; i <= N; ++i) { for (int j = 1 ; j <= N; ++j) { cout << i*j << " " ; } cout << endl; } } return 0 ; }
问题 C: 找规律填数字 题目描述 小宇正在读小学,今天老师布置了几道数学题目。小宇平时上课经常不专心,这些他可发愁了,怎么办呢?看看你能不能帮帮他。 题目是给你一组有规律序列的前面5个整数,请你给出它后面跟着的5个整数,如:1,2,3,4,5,, ,_, ,___。这是个等差数列,后面应该是6,7,8,9,10,就这么简单。而且现在小宇已经知道这串序列要么是等差数列,要么是等比数列或者是斐波那契数列。
输入 输入包含多组测试数据。每组输入5个整数,每个数字之间隔一个空格,当5个数字都为0时输入结束。
输出 对于每组输入,输出这串数列的后面5个数字,每个数字之间隔一个空格。
样例输入 1 2 3 4 1 2 3 4 5 1 2 4 8 16 1 2 3 5 8 0 0 0 0 0
样例输出 1 2 3 6 7 8 9 10 32 64 128 256 512 13 21 34 55 89
参考答案 查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include <iostream> using namespace std;bool isDis (int * arr) { int distant = arr[1 ]-arr[0 ]; for (int i = 1 ; i < 4 ; ++i) { if ((arr[i+1 ]-arr[i])!=distant) return false ; } return true ; } bool isFib (int * arr) { for (int i = 0 ; i < 3 ; ++i) { if (arr[i] + arr[i+1 ] != arr[i+2 ]) return false ; } return true ; } void outDis (int num, int dis) { for (int i = 0 ; i < 5 ; ++i) { cout << num+dis << " " ; num += dis; } cout << endl; } void outGeo (int num, int pro) { for (int i = 0 ; i < 5 ; ++i) { cout << num*pro << " " ; num *= pro; } cout << endl; } void outFib (int num1, int num2) { for (int i = 0 ; i < 5 ; ++i) { cout << num1 + num2 << " " ; int tmp = num1; num1 = num2; num2 += tmp; } cout << endl; } int main () { int arr[5 ]; while (true ) { cin >> arr[0 ] >> arr[1 ] >> arr[2 ] >> arr[3 ] >> arr[4 ]; bool flag = true ; for (auto it : arr) { if (it!=0 ) flag = false ; } if (flag) break ; if (isDis (arr)) { outDis (arr[4 ], arr[1 ]-arr[0 ]); } else if (isFib (arr)) { outFib (arr[3 ], arr[4 ]); } else { outGeo (arr[4 ], arr[1 ]/arr[0 ]); } } return 0 ; }
问题 D: 复原二叉树 题目描述 小明在做数据结构的作业,其中一题是给你一棵二叉树的前序遍历和中序遍历结果,要求你写出这棵二叉树的后序遍历结果。
输入 输入包含多组测试数据。每组输入包含两个字符串,分别表示二叉树的前序遍历和中序遍历结果。每个字符串由不重复的大写字母组成。
输出 对于每组输入,输出对应的二叉树的后续遍历结果。
样例输入 1 2 DBACEGF ABCDEFG BCAD CBAD
样例输出
参考答案 查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <iostream> #include <bits/stdc++.h> using namespace std;struct node { char data; node *lChild, *rChild; }; node* getNewNode (char & data) { return new node ({data, nullptr , nullptr }); } node* mergeTree (string preS, string inS) { if (preS.empty ()) return nullptr ; if (preS.length ()==1 ) return getNewNode (preS[0 ]); node* root = getNewNode (preS[0 ]); if (inS[0 ]==preS[0 ]) { root->rChild = mergeTree (string (preS.begin ()+1 , preS.end ()), string (inS.begin ()+1 , inS.end ())); } else { int k = 0 ; while (inS[k]!=preS[0 ]) { ++k; } root->lChild = mergeTree (string (preS.begin ()+1 , preS.begin ()+1 +k), string (inS.begin (), inS.begin ()+k)); root->rChild = mergeTree (string (preS.begin ()+1 +k, preS.end ()), string (inS.begin ()+1 +k, inS.end ())); } return root; } void postOrder (node* root) { if (root==nullptr ) return ; postOrder (root->lChild); postOrder (root->rChild); cout << root->data; } void clear (node* root) { if (root==nullptr ) return ; clear (root->lChild); clear (root->rChild); delete root; } int main () { string s, preS, inS; while (getline (cin, s)) { preS.assign (s, 0 , s.length ()/2 ); inS.assign (s, (s.length ()+2 )/2 , s.length ()/2 ); node* root = mergeTree (preS, inS); postOrder (root); cout << endl; s.clear (); clear (root); if (cin.peek () == '\n' ) break ; } return 0 ; }
问题 E: 子树的后序遍历 题目描述 给你一颗二叉树的中序和后序遍历序列,请编程输出该二叉树左子树或右子树的后序遍历序列。
输入 占三行,第一行表示二叉树的中序遍历序列,第二行表示后序遍历序列。用大写字母标识结点,二叉树的结点最多26个。 第三行是单个字母,L表示要求输出该二叉树的左子树的后序遍历序列,R表示要求输出该二叉树的右子树的后序遍历序列。
输出 按要求输出该二叉树左子树或右子树的后序遍历序列。
样例输入
样例输出
参考答案 这里我偷了个懒,直接把字符串倒过来,用上一问的代码做的
查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <iostream> #include <bits/stdc++.h> using namespace std;struct node { char data; node *lChild, *rChild; }; node* getNewNode (char & data) { return new node ({data, nullptr , nullptr }); } node* mergeTree (string preS, string inS) { if (preS.empty ()) return nullptr ; if (preS.length ()==1 ) return getNewNode (preS[0 ]); node* root = getNewNode (preS[0 ]); if (inS[0 ]==preS[0 ]) { root->lChild = mergeTree (string (preS.begin ()+1 , preS.end ()), string (inS.begin ()+1 , inS.end ())); } else { int k = 0 ; while (inS[k]!=preS[0 ]) { ++k; } root->rChild = mergeTree (string (preS.begin ()+1 , preS.begin ()+1 +k), string (inS.begin (), inS.begin ()+k)); root->lChild = mergeTree (string (preS.begin ()+1 +k, preS.end ()), string (inS.begin ()+1 +k, inS.end ())); } return root; } void postOrder (node* root) { if (root==nullptr ) return ; postOrder (root->lChild); postOrder (root->rChild); cout << root->data; } void clear (node* root) { if (root==nullptr ) return ; clear (root->lChild); clear (root->rChild); delete root; } int main () { string s, preS, inS; cin >> preS >> inS; char flag; cin >> flag; reverse (preS.begin (), preS.end ()); reverse (inS.begin (), inS.end ()); node* root = mergeTree (inS, preS); if (flag == 'L' ) postOrder (root->lChild); else postOrder (root->rChild); s.clear (); clear (root); return 0 ; }
问题 F: 迷宫问题 题目描述 小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。 小明只能向上下左右四个方向移动。
输入 输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。 每组输入的第一行是两个整数N和M(1<=N,M<=100)。 接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。 字符的含义如下: ‘S’:起点 ‘E’:终点 ‘-’:空地,可以通过 ‘#’:障碍,无法通过 输入数据保证有且仅有一个起点和终点。
输出 对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。
样例输入 1 2 3 4 5 6 7 1 5 5 S-### ----- ##--- E#--- ---##
样例输出
参考答案 使用BFS 做,DFS会超时
查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #include <iostream> #include <queue> #include <vector> using namespace std;int N, M;bool l[105 ][105 ];struct point { int x; int y; int step; }; vector<pair<int , int >> v; bool canMove (point& p) { if (p.x >= 0 && p.y >= 0 && p.x < M && p.y < N && l[p.y][p.x]) { return true ; } return false ; } int move_ming (pair<int , int > S, pair<int , int >& E) { if (S==E) return 0 ; queue<point> q; q.push (point ({S.second, S.first, 0 })); l[S.first][S.second] = false ; while (!q.empty ()) { point p = q.front (); for (int i = 0 ; i < 4 ; ++i) { point next_p = point ({p.x+v[i].second, p.y+v[i].first, p.step+1 }); if (canMove (next_p)) { if (next_p.x == E.second && next_p.y == E.first) { return next_p.step; } q.push (next_p); l[next_p.y][next_p.x] = false ; } } q.pop (); } return -1 ; } int main () { v.push_back (pair <int , int >(-1 , 0 )); v.push_back (pair <int , int >(1 , 0 )); v.push_back (pair <int , int >(0 , 1 )); v.push_back (pair <int , int >(0 , -1 )); int T; cin >> T; while (T--) { cin >> N >> M; pair<int , int > S, E; for (int i = 0 ; i < N; ++i) { for (int j = 0 ; j < M; ++j) { l[i][j] = false ; } } char sign; for (int i = 0 ; i < N; ++i) { for (int j = 0 ; j < M; ++j) { cin >> sign; if (sign == '-' ) { l[i][j] = true ; } else if (sign == '#' ) { l[i][j] = false ; } else if (sign == 'S' ) { l[i][j] = true ; S.first = i; S.second = j; } else if (sign == 'E' ) { l[i][j] = true ; E.first = i; E.second = j; } } } cout << move_ming (S, E) << endl; } return 0 ; }