Homework New

This commit is contained in:
e2hang
2025-11-27 13:40:37 +08:00
parent b84c3ba783
commit 4965074539
39 changed files with 2191 additions and 832 deletions

View File

@@ -1,108 +0,0 @@
#include <iostream>
using namespace std;
template <class T>
struct Node {
T element;
Node<T>* next;
Node(const T& e, Node<T>* n = nullptr) : element(e), next(n) {}
};
template <class T>
class Chain {
private:
Node<T>* head;
int size;
public:
Chain() : head(nullptr), size(0) {}
~Chain() {
while (head != nullptr) {
Node<T>* tmp = head;
head = head->next;
delete tmp;
}
}
void insert(int pos, const T& e) {
if (pos < 0 || pos > size) {
throw invalid_argument("Invalid insert position");
}
if (pos == 0) {
head = new Node<T>(e, head);
} else {
Node<T>* prev = head;
for (int i = 0; i < pos - 1; i++) {
prev = prev->next;
}
prev->next = new Node<T>(e, prev->next);
}
size++;
}
void erase(int pos) {
if (pos < 0 || pos >= size) {
throw invalid_argument("Invalid erase position");
}
Node<T>* toDelete;
if (pos == 0) {
toDelete = head;
head = head->next;
} else {
Node<T>* prev = head;
for (int i = 0; i < pos - 1; i++) {
prev = prev->next;
}
toDelete = prev->next;
prev->next = toDelete->next;
}
delete toDelete;
size--;
}
void print() const {
Node<T>* cur = head;
while (cur != nullptr) {
cout << cur->element << " ";
cur = cur->next;
}
cout << endl;
}
};
int main(){
int n;
cin >> n;
Chain<int> list;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
try {
list.insert(i, x);
}
catch(const invalid_argument& e) {}
}
int m;
cin >> m;
for (int i = 0; i < m; i++) {
int op, k, d;
cin >> op;
if (op == 0) {
cin >> k >> d;
try {
list.insert(k, d);
} catch(const invalid_argument& e) {}
} else if (op == 1) {
cin >> k;
try {
list.erase(k - 1);
} catch(const invalid_argument& e) {}
}
}
list.print();
return 0;
}

View File

@@ -1,83 +0,0 @@
#include <iostream>
#include <limits>
using namespace std;
template <class T>
class Stack {
T* element;
int length;
int stackTop;
const T INF = std::numeric_limits<T>::max();
public:
Stack(int l) {
stackTop = -1;
length = l;
element = new T[l];
}
~Stack() {
delete[] element;
}
T& top() {
if (stackTop == -1) throw std::invalid_argument("No Top Element.");
return element[stackTop];
}
void pop() {
if (stackTop == -1) throw std::invalid_argument("No Top Element.");
stackTop--;
}
void push(const T& e) {
if (stackTop == length - 1) {
T* tmp = new T[2 * length];
for (int i = 0; i < length; i++) {
tmp[i] = element[i];
}
delete[] element;
element = tmp;
length *= 2;
}
stackTop++;
element[stackTop] = e;
}
bool empty() const {
return stackTop == -1;
}
};
int main() {
int n;
cin >> n;
Stack<int> s(n);
for (int i = 0; i < n; i++) {
int p;
cin >> p;
switch (p) {
case 0: {
if (!s.empty()) {
cout << s.top() << endl;
s.pop();
} else {
cout << "invalid" << endl;
}
break;
}
case 1: {
int val;
cin >> val;
s.push(val);
break;
}
default:
return 0;
}
}
return 0;
}

View File

@@ -1,94 +0,0 @@
#include <iostream>
#include <limits>
using namespace std;
template <class T>
class Queue {
private:
T* element;
int begin;
int end;
int capacity;
public:
static constexpr T INF = numeric_limits<T>::max();
Queue(int len) : begin(0), end(0), capacity(len) {
element = new T[len];
}
~Queue() {
delete[] element;
}
void push(const T& e) {
if (end == capacity) {
int newCap = capacity * 2;
T* tmp = new T[newCap];
for (int i = begin; i < end; i++) {
tmp[i - begin] = element[i];
}
end -= begin;
begin = 0;
capacity = newCap;
delete[] element;
element = tmp;
}
element[end++] = e;
}
void pop() {
if (empty()) throw std::invalid_argument("Queue is empty.");
begin++;
}
T& front() {
if (empty()) throw std::invalid_argument("Queue is empty.");
return element[begin];
}
T& back() {
if (empty()) throw std::invalid_argument("Queue is empty.");
return element[end - 1];
}
bool empty() const {
return begin == end;
}
int size() const {
return end - begin;
}
};
int main() {
int n;
cin >> n;
Queue<int> q(n);
for (int i = 0; i < n; i++) {
int p;
cin >> p;
switch (p) {
case 0: {
if (q.empty()) {
cout << "invalid" << endl;
} else {
cout << q.front() << endl;
q.pop();
}
break;
}
case 1: {
int val;
cin >> val;
q.push(val);
break;
}
default: {
return 0;
}
}
}
return 0;
}

View File

@@ -1,71 +0,0 @@
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<int> build_next(const string& p) {
int n = p.size(); // 模式串长度
vector<int> nxt(n, 0); // 存放 next 数组,初始化全 0
for (int i = 1, j = 0; i < n; i++) {
// --- step1: 如果当前字符不匹配,回退 j ---
while (j > 0 && p[i] != p[j])
j = nxt[j - 1]; // j 回退到上一个最长前后缀的长度,采用动态规划思想
// --- step2: 如果匹配成功j 前进 ---
if (p[i] == p[j])
j++;
// --- step3: 记录当前前缀的 next 值 ---
nxt[i] = j; // 表示 p[0..i] 的最长公共前后缀长度
}
return nxt;
}
vector<int> next_arr(const string& x) {
int n = x.size();
vector<int> tmp(n, 0);
for (int i = 0; i < n; i++) {
int j = 0;
for (int len = i; len > 0; len--) {
if (x.substr(0, len) == x.substr(i - len + 1, len)) {
j = len;
break;
}
}
tmp[i] = j;
}
return tmp;
}
int main(){
string mod, input;
cin >> input >> mod;
vector<int> next = build_next(mod);
int n = mod.size();
int pi = 0, pm = 0;
cout << next[n / 4] << " " << next[n / 2] << " " << next[3 * n / 4] << endl;
while (pi < input.size()) {
if (input[pi] == mod[pm]) {
pi++;
pm++;
if (pm == mod.size()) {
cout << pi - pm << " "; // 匹配位置(起始下标)
return 0;
pm = next[pm - 1]; // 回退
}
} else {
if (pm > 0)
pm = next[pm - 1]; // 回退
else
pi++;
}
}
cout << -1 << endl;
return 0;
}
qwerababcabcabcabcdaabcabhlk

43
Exercise/Homework1/Q1.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include <iostream>
#include <string>
using namespace std;
int map(char c) {
if (c == '{') return 4;
if (c == '[') return 3;
if (c == '(') return 2;
if (c == '<') return 1;
return 0;
}
bool match(char a, char b) {
return (a == '(' && b == ')') || (a == '[' && b == ']') || (a == '{' && b == '}') || (a == '<' && b == '>');
}
bool check(const string& s) {
string front;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '{' || s[i] == '[' || s[i] == '(' || s[i] == '<') {
if (!front.empty() && map(front.back()) <= map(s[i]))
return false;
front.push_back(s[i]);
} else if (s[i] == '}' || s[i] == ']' || s[i] == ')' || s[i] == '>') {
if (front.empty() || !match(front.back(), s[i]))
return false;
front.pop_back();
}
}
return front.empty();
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
string s;
cin >> s;
cout << (check(s) ? "Match" : "Fail") << endl;
}
return 0;
}

50
Exercise/Homework1/Q2.rs Normal file
View File

@@ -0,0 +1,50 @@
use std::io::{self, Read, Write};
fn main() {
/*
let mut s = String::new();
io::stdin().read_line(&mut s).unwrap();
let n: usize = s.trim().parse().unwrap();
let mut nums: Vec<i64> = Vec::new();
let mut max: i64 = 0;
for _ in 0..n {
let mut x = String::new();
io::stdin().read_line(&mut x).unwrap();
let a: i64 = x.trim().parse().unwrap();
nums.push(a);
if a > max {
max = a;
}*/
// //输入太慢了过不了
let mut buf = String::new();
io::stdin().read_to_string(&mut buf).unwrap();
let mut it = buf.split_whitespace();
let m: usize = it.next().unwrap().parse().unwrap();
let mut vec: Vec<i64> = Vec::with_capacity(m);
let mut max: i64 = 0;
for _ in 0..m {
let a: i64 = it.next().unwrap().parse().unwrap();
vec.push(a);
if a > max { max = a; }
}
let mut dp: Vec<i64> = vec![0; (max + 1) as usize];
if max >= 0 { dp[0] = 1; }
if max >= 1 { dp[1] = 1; }
if max >= 2 { dp[2] = 2; }
if max >= 3 { dp[3] = 4; }
for i in 4..=max {
dp[i as usize] = dp[(i - 1) as usize] + dp[(i - 2) as usize] + dp[(i - 3) as usize] + dp[(i - 4) as usize];
}
let mut out = String::new();
for i in vec {
out.push_str(&format!("{}\n", dp[i as usize]));
}
io::stdout().write_all(out.as_bytes()).unwrap();
}

39
Exercise/Homework1/Q3.rs Normal file
View File

@@ -0,0 +1,39 @@
use std::io;
pub struct Status{
pos: i32,
a: char, // from
b: char, // to
c: char // aux
}
fn main(){
let mut s = String::new();
io::stdin().read_line(&mut s).unwrap();
let n: i32 = s.trim().parse().unwrap();
let mut stack: Vec<Status> = Vec::new();
stack.push(Status{pos: n, a: 'A', b: 'C', c: 'B'});
let mut max = 0;
let mut output = String::new(); //输出,要不然太慢总会超时
while !stack.is_empty() {
if stack.len() > max {
max = stack.len();
}
let mut end = stack.pop().unwrap();
if end.pos == 1 {
output.push_str(&format!("Move disk from {} to {}\n", end.a, end.b));
} else {
stack.push(Status{pos: end.pos - 1, a: end.c, b: end.b, c: end.a});
stack.push(Status{pos: 1, a: end.a, b: end.b, c: end.c});
stack.push(Status{pos: end.pos - 1, a: end.a, b: end.c, c: end.b});
}
}
print!("{}", output);
println!("{}", max);
}

View File

@@ -1,167 +1,103 @@
``` html
A 单链表基本操作
分数 10
作者 朱允刚
单位 吉林大学
请编写程序实现单链表插入、删除结点等基本算法。给定一个单链表和一系列插入、删除结点的操作序列,输出实施上述操作后的链表。单链表数据域值为整数。
Q1
```
编写程序检查给定字符串中包含的括号是否正确匹配,本题中的括号有{ }、[ ]、( )、< >四种。另外再加上一个新的约束条件:当有多种括号嵌套时,嵌套的顺序应为{ → [ → ( → <即ag+b[(d<ef>)]、a+[b+(cd)e]都是正确的匹配而a+(b[c+d])则不是正确匹配。注意本题不允许相同类型括号的嵌套即a+(b(c+d))不是正确匹配。本题不需要判断表达式是否合法,只需判断字符串中包含的括号是否正确匹配。
输入格式:
输入第1行为1个正整数n表示当前单链表长度第2行为n个空格间隔的整数为该链表n个元素的数据域值。第3行为1个正整数m表示对该链表施加的操作数量接下来m行,每行表示一个操作为2个或3个整数格式为0 k d或1 k。0 k d表示在链表第k个结点后插入一个数据域值为d的结点若k=0则表示表头插入。1 k表示删除链表中第k个结点此时k不能为0。注操作序列中若含有不合法的操作如在长度为5的链表中删除第8个结点、删除第0个结点等则忽略该操作。n和m不超过100000
第一行为一个整数n表示字符串的个数。接下来n行,每行为一个字符串。1<n≤100字符串长度不超过1000。
输出格式:
输出为一行整数表示实施上述m个操作后的链表每个整数后一个空格。输入数据保证结果链表不空。
对于每个字符串,若为正确匹配则输出"Match" ,若不匹配则输出"Fail"。
输入样例:
5
1 2 3 4 5
5
0 2 8
0 9 6
0 0 7
1 0
1 6
输出样例:
7 1 2 8 3 5
代码长度限制
16 KB
Python (python3)
时间限制
1000 ms
内存限制
256 MB
Java (javac)
时间限制
5000 ms
内存限制
256 MB
其他编译器
时间限制
100 ms
内存限制
10 MB
栈限制
8192 KB
---
B 栈的实现及基本操作
分数 10
作者 朱允刚
单位 吉林大学
给定一个初始为空的栈和一系列压栈、弹栈操作请编写程序输出每次弹栈的元素。栈的元素值均为整数。本题不允许使用stack、queue、vector等STL容器。
输入格式:
输入第1行为1个正整数n表示操作个数接下来n行每行表示一个操作格式为1 d或0。1 d表示将整数d压栈0表示弹栈。n不超过20000。
输出格式:
按顺序输出每次弹栈的元素每个元素一行。若某弹栈操作不合法如在栈空时弹栈则对该操作输出invalid。
输入样例:
7
1 1
1 2
0
0
0
1 3
0
输出样例:
2
1
invalid
3
代码长度限制
16 KB
时间限制
50 ms
内存限制
10 MB
栈限制
131000 KB
---
C 队列的实现及基本操作
分数 10
作者 朱允刚
单位 吉林大学
给定一个初始为空的队列和一系列入队、出队操作,请编写程序输出每次出队的元素。队列的元素值均为整数。
备注本题不允许使用stack、queue、vector等STL容器。
输入格式:
输入第1行为1个正整数n表示操作个数接下来n行每行表示一个操作格式为1 d或0。1 d表示将整数d入队0表示出队。n不超过20000。
输出格式:
按顺序输出每次出队的元素每个元素一行。若某出队操作不合法如在队列空时出队则对该操作输出invalid。
输入样例:
7
1 1
1 2
0
0
0
1 3
0
输出样例:
1
2
invalid
3
代码长度限制
16 KB
时间限制
50 ms
内存限制
20 MB
栈限制
8192 KB
---
D KMP模式匹配算法
分数 10
作者 朱允刚
单位 吉林大学
给定目标串s和模式串p编写程序使用KMP算法进行模式匹配计算p在s中首次出现的位置若p不在s中则输出1。字符串下标从0开始。
输入格式:
输入为2行第1行为主串s第2行为模式串p。主串和模式串长度不超过10
5
输出格式:
输出为2行第1行为3个整数表示分别在模式串p的p
m/4
,p
2m/4
,p
3m/4
处失配后模式串下一次匹配的位置即next[j]或f[j1]+1的值j=m/4,2m/4,3m/4每个整数后一个空格m表示模式串p的长度第2行为一个整数表示p在s中首次出现的位置若p不在s中则输出1。
输入样例:
qwerababcabcabcabcdaabcabhlk
abcabcabcabc
输出样例:
0 3 6
输入样例1:
8
a+(b*[c+d])
g{b[(<c>)d]e}x
[()]
((()))
<>()[]{}
[{}]
x=y+{z+(b)}
][()
输出样例1:
Fail
Match
Match
Fail
Match
Fail
Match
Fail
输入样例2:
6
{[afds(a<afd>)]}yt
[()rew]
<>()[wre]{}
[{qw}]
rew{(weq)}jjk
<><{}>[][](){[{}]}
输出样例2:
Match
Match
Match
Fail
Match
Fail
代码长度限制
16 KB
时间限制
20 ms
50 ms
内存限制
10 MB
30 MB
栈限制
8192 KB
```
Q2
```
从A点到B点有n个格子小明现在要从A点到B点小明吃了些东西补充了一下体力他可以一步迈一个格子也可以一步迈两个格子也可以一步迈3个格子也可以一步迈4个格子。请编写程序计算小明从A点到B点一共有多少种走法。
grid2.jpg
输入格式:
输入包含多组数据第一行为一个整数mm不超过10000表示输入数据组数。接下来m行每行为一个整数nn不超过100且保证对应的结果小于2
31
表示从A点到B点的格子数。
输出格式:
输出为m个整数表示对于每组数据小明从A点到B点的走法数。
输入样例:
2
5
3
输出样例:
15
4
```
Q3
```
本学期的《数据结构》课上老师曾结合汉诺塔问题介绍了使用栈消除递归的方法从而将汉诺塔问题的递归算法转换为非递归算法本题请你编程实现上述非递归算法即使用栈以非递归形式求解汉诺塔问题。将n个圆盘自A柱移至C柱可途经B柱并输出求解过中栈的最大容量最多存储了多少个四元组
备注:本题将在机器评测后进行人工核验若有同学未按题目要求仅使用递归程序通过本题本题记为0分。
image.png
输入格式:
输入为一个整数n表示初始时A柱上的圆盘数目n不超过20。
输出格式:
按顺序输出各动作每个动作占一行格式为“Move disk from x to y”表示将x柱顶端的圆盘移至y柱。
最后一行为一个整数,表示求解过程中栈的最大容量。
输入样例:
3
输出样例:
Move disk from A to C
Move disk from A to B
Move disk from C to B
Move disk from A to C
Move disk from B to A
Move disk from B to C
Move disk from A to C
5
```