diff --git a/Algorithm/BackTracking/readme.md b/Algorithm/BackTracking/readme.md new file mode 100644 index 0000000..a327154 --- /dev/null +++ b/Algorithm/BackTracking/readme.md @@ -0,0 +1,80 @@ +回溯法(Backtracking)是一种**系统地枚举所有可能解**的方法,通常用于解决**组合、排列、约束满足等问题**。它的核心思想是:在搜索问题的解空间时,如果发现当前部分解无法得到最终解,就**立即放弃(回溯)**,避免无谓的计算。 + +我给你拆开讲: + +--- + +### 1️⃣ 基本思路 + +1. 从问题的初始状态开始,尝试每一种可能的选择。 +2. 对于每一种选择: + + * 判断是否符合条件(约束)。 + * 如果符合,就继续尝试下一步。 + * 如果不符合,直接放弃(剪枝)。 +3. 当到达最终状态时,把解记录下来。 +4. 搜索完当前选择后,撤销选择(回到上一步),尝试其他可能。 + +这个“尝试→失败→撤销→尝试其他”过程就是“回溯”。 + +--- + +### 2️⃣ 典型问题 + +回溯法适合解决这类问题: + +* **排列问题**:生成1\~n的所有排列。 +* **组合问题**:从n个元素中选出k个组合。 +* **子集问题**:生成所有子集。 +* **棋盘类问题**:N皇后、数独、填字游戏。 +* **约束满足问题**:图着色、八数码问题等。 + +--- + +### 3️⃣ 模板代码(C++示例) + +以**N皇后问题**为例: + +```cpp +vector queens; // queens[i] = 列号 +int n; + +bool isValid(int row, int col) { + for(int i = 0; i < row; i++) { + int c = queens[i]; + if(c == col || abs(c - col) == row - i) + return false; + } + return true; +} + +void backtrack(int row) { + if(row == n) { + // 找到一个解 + for(int c : queens) cout << c << " "; + cout << endl; + return; + } + for(int col = 0; col < n; col++) { + if(isValid(row, col)) { + queens.push_back(col); // 选择 + backtrack(row + 1); // 递归 + queens.pop_back(); // 回溯 + } + } +} +``` + +--- + +### 4️⃣ 总结 + +* 回溯法是一种**DFS+剪枝**的方法。 +* 核心是**选择、约束、递归、撤销**。 +* 常用于**枚举问题、组合问题和约束满足问题**。 + +--- + +如果你愿意,我可以给你画一张**回溯法搜索树的示意图**,直观理解它是怎么“尝试、失败、回退”的。 + +你想让我画吗? diff --git a/Algorithm/BackTracking/回溯 b/Algorithm/BackTracking/回溯 deleted file mode 100644 index e69de29..0000000 diff --git a/Algorithm/Graph/BFS/Maze.cpp b/Algorithm/Graph/BFS/Maze.cpp new file mode 100644 index 0000000..f4e3f74 --- /dev/null +++ b/Algorithm/Graph/BFS/Maze.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +using namespace std; +// +int dx[4] = {0, 0, -1, 1}; +int dy[4] = {1, -1, 0, 0}; +int dxx[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; +int dyy[8] = {1, 0, -1, 1, -1, 1, 0, -1}; +int main(){ + deque> q; + int n, m; + // + cin >> n >> m; + int startx, starty; + // + cin >> startx >> starty; + + deque> maze; + deque> visited; + deque> dist(n, deque(m, 0)); // + maze.resize(n); + visited.resize(n, deque(m, false)); + int tmp; + //0ʾǽ1ʾ· + for(int i = 0; i < n; i++){ + for(int j = 0; j < m; j++){ + cin >> tmp; + maze[i].push_back(tmp); + } + } + tmp = 0; + q.push_back(make_pair(startx, starty)); + while(!q.empty()){ + pair u = q.front(); + q.pop_front(); + int x = u.first, y = u.second; + visited[x][y] = true; + + for(int i = 0; i < 4; i++){ + if(x + dx[i] >= 0 && x + dx[i] < n && y + dy[i] >= 0 && y + dy[i] < m && !visited[x + dx[i]][y + dy[i]] && maze[x + dx[i]][y + dy[i]] == 1){ + visited[x + dx[i]][y + dy[i]] = true; + dist[x + dx[i]][y + dy[i]] = dist[x][y] + 1; // ¾ + q.push_back(make_pair(x + dx[i], y + dy[i])); + } + } + } + cout << endl; + for(int i = 0; i < n; i++){ + for(int j = 0; j < m; j++){ + cout << dist[i][j] << " "; + } + cout << endl; + } + return 0; +} +/* +6 5 +0 0 +1 1 0 1 1 +1 0 1 1 1 +1 0 1 0 0 +1 0 1 1 1 +1 1 1 0 1 +1 1 1 1 1 +*/ diff --git a/Algorithm/Graph/DFS/UVa572-Oil-Deposits.cpp b/Algorithm/Graph/DFS/UVa572-Oil-Deposits.cpp new file mode 100644 index 0000000..0925a36 --- /dev/null +++ b/Algorithm/Graph/DFS/UVa572-Oil-Deposits.cpp @@ -0,0 +1,51 @@ +#include +#include +using namespace std; +int m = 5, n = 5; +vector> s; +vector> visited; +vector> ids; + + +void dfs(int x, int y, int id){ + if(x < 0 || x >= m || y < 0 || y >=n) return; + if(s[x][y] != '@') return; + if(visited[x][y] == true) return; + visited[x][y] = true; + ids[x][y] = id; + dfs(x - 1, y - 1, id + 1); + dfs(x - 1, y, id + 1); + dfs(x - 1, y + 1, id + 1); + dfs(x, y - 1, id + 1); + dfs(x, y + 1, id + 1); + dfs(x + 1, y - 1, id + 1); + dfs(x + 1, y, id + 1); + dfs(x + 1, y + 1, id + 1); + cout << id << " "; +} + +int main(){ + s.resize(m); + visited.assign(m, vector(n, false)); + ids.assign(m, vector(n, 0)); + char tmp; + for(int i = 0; i < m; i++){ + for(int j = 0; j < n; j++){ + cin >> tmp; + s[i].push_back(tmp); + } + } + for(int i = 0; i < m; i++){ + for(int j = 0; j < n; j++){ + if(!visited[i][j] && s[i][j] == '@') dfs(i, j, 1); + } + } + cout << endl; + int max = -1; + for(int i = 0; i < m; i++){ + for(int j = 0; j < n; j++){ + if(ids[i][j] > max) max = ids[i][j]; + } + } + cout << max << endl; +} diff --git a/Algorithm/Graph/EulerGraph/UVa-10129-PlayOnWords.cpp b/Algorithm/Graph/EulerGraph/UVa-10129-PlayOnWords.cpp new file mode 100644 index 0000000..c9fca5d --- /dev/null +++ b/Algorithm/Graph/EulerGraph/UVa-10129-PlayOnWords.cpp @@ -0,0 +1,80 @@ +#include +#include +#include +#include +using namespace std; +struct Graph{ + int v; + int e; + vector> adj; + vector visited; + + Graph(int _v) : v(_v) { + adj.resize(v); + visited.assign(v, false); + } + bool validateV(int _v){ + return ( _v >= 0 && _v < v); + } + void insert(int _a, int _b){ + if(!validateV(_a) || !validateV(_b)) return; + + adj[_a].push_back(_b); + } + int degree(int _v){ + if(!validateV(_v)) return 0; + return outDegree(_v) + inDegree(_v); + } + int outDegree(int _v){ + if(!validateV(_v)) return 0; + return adj[_v].size(); + } + int inDegree(int _v){ + if(!validateV(_v)) return 0; + int js = 0; + for(auto x : adj){ + for(int i = 0; i < x.size(); i++){ + if(x[i] == _v) js++; + } + } + return js; + } + void dfs(int _v){ + if(!validateV(_v)) return; + if(visited[_v]) return; + visited[_v] = true; + for(auto x : adj[_v]){ + dfs(x); + } + } + bool isConnected(){ + dfs(0); + for(auto x : visited){ + if(!x) return false; + } + + int js = 0; + for(int i = 0; i < v; i++){ + if(degree(i) % 2 == 1) js++; + } + return (js == 0) || (js == 2); + } +}; +int main(){ + int n; + cin >> n; + Graph g(n); + vector s; + s.resize(n); + for(int i = 0; i < n; i++){ + cin >> s[i]; + } + for(int i = 0; i < n; i++){ + for(int j = 0; j < n; j++){ + if(i != j && s[i].back() == s[j].front()) g.insert(i, j); + } + } + g.isConnected() ? cout << "YES" << endl : cout << "NO" << endl; + system("pause"); + return 0; +} diff --git a/Algorithm/List/UVA11988 破损的键盘 Broken Keyboard (a.k.a. Beiju Text).cpp b/Algorithm/List/UVA11988 破损的键盘 Broken Keyboard (a.k.a. Beiju Text).cpp new file mode 100644 index 0000000..0162157 --- /dev/null +++ b/Algorithm/List/UVA11988 破损的键盘 Broken Keyboard (a.k.a. Beiju Text).cpp @@ -0,0 +1,30 @@ +#include +#include +#include +using namespace std; + +int main() { + string line; + while (getline(cin, line)) { // һζһУֱ EOF + list s; + auto it = s.begin(); + + for (char tmp : line) { + if (tmp == '[') { + it = s.begin(); + } + else if (tmp == ']') { + it = s.end(); + } + else { + it = s.insert(it, tmp); + ++it; + } + } + + for (char c : s) cout << c; + cout << '\n'; // ÿһ + } + return 0; +} + diff --git a/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 set不过.cpp b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 set不过.cpp new file mode 100644 index 0000000..52ffcf0 --- /dev/null +++ b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 set不过.cpp @@ -0,0 +1,19 @@ +#include +#include +using namespace std; +int main(){ + multiset s; + int n, m; + cin >> n >> m; + int tmp; + for(int i = 0; i < n; i++){ + cin >> tmp; + s.emplace(tmp); + } + int js = 0; + for(auto it = s.begin(); it != s.end(); it++){ + js += s.count(*it - m); + } + cout << js << endl; + return 0; +} diff --git a/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_map.cpp b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_map.cpp new file mode 100644 index 0000000..50a4884 --- /dev/null +++ b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_map.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +// hash + map ԭDzϣ O(n^2) +using namespace std; +int main(){ + unordered_map s; + vector arr; + long long n, m; + cin >> n >> m; + long long tmp; + for(int i = 0; i < n; i++){ + cin >> tmp; + arr.push_back(tmp); + s[tmp]++; + } + long long need; + long long js = 0; + for(int i = 0; i < n; i++){ + need = arr[i] - m; + if(s.count(need)) js += s[need];//s[need]ֵ pair.seconds + //s.emplace(make_pair(arr[i], 1));//Уarr[i]ڣֱӷ + } + cout << js << endl; + return 0; +} diff --git a/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_map.exe b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_map.exe new file mode 100644 index 0000000..9e83ce8 Binary files /dev/null and b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_map.exe differ diff --git a/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_set不过 有重复.cpp b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_set不过 有重复.cpp new file mode 100644 index 0000000..6b1d1c7 --- /dev/null +++ b/Algorithm/Maths/P1102 A-B数对/P1102 A-B 数对 unordered_set不过 有重复.cpp @@ -0,0 +1,19 @@ +#include +#include +using namespace std; +int main(){ + unordered_multiset s; + int n, m; + cin >> n >> m; + int tmp; + for(int i = 0; i < n; i++){ + cin >> tmp; + s.emplace(tmp); + } + int js = 0; + for(auto it = s.begin(); it != s.end(); it++){ + js += s.count(*it - m); + } + cout << js << endl; + return 0; +} diff --git a/Algorithm/Recursion/UVA699 下落的树叶 The Falling Leaves.cpp b/Algorithm/Recursion/UVA699 下落的树叶 The Falling Leaves.cpp new file mode 100644 index 0000000..74e651b --- /dev/null +++ b/Algorithm/Recursion/UVA699 下落的树叶 The Falling Leaves.cpp @@ -0,0 +1,24 @@ +#include +#include +using namespace std; +//Ƿ + +map sum; +void build(int p){ + int tmp; + cin >> tmp; + if(tmp == -1) return; + sum[p] += tmp; + build(p - 1); + build(p + 1); +} + +int main(){ + build(0); + if(!sum.empty()){ + for(auto it = sum.begin(); it != sum.end(); ++it){ + cout << it->second << " "; + } + } + return 0; +} diff --git a/Algorithm/Recursion/UVa839 天平Not_so_Mobile.cpp b/Algorithm/Recursion/UVa839 天平Not_so_Mobile.cpp new file mode 100644 index 0000000..4a61799 --- /dev/null +++ b/Algorithm/Recursion/UVa839 天平Not_so_Mobile.cpp @@ -0,0 +1,58 @@ +#include +//ǰ ݹ컨 +using namespace std; +struct mobile{ + double lw, ll, rw, rl; + double weight; + mobile* left; + mobile* right; + + mobile(double a, double b, double c, double d) : lw(a), ll(b), rw(c), rl(d), left(nullptr), right(nullptr) {} +}; + +bool solve(mobile* &x){ + double a, b, c, d; + bool b1 = true, b2 = true; + cin >> a >> b >> c >> d; + x = new mobile(a, b, c, d); + if(!x->lw) b1 = solve(x->left); + if(!x->rw) b2 = solve(x->right); + double leftWeight = x->left ? x->left->weight : x->lw; + double rightWeight = x->right ? x->right->weight : x->rw; + x->weight = leftWeight + rightWeight; + //עreturnsolveһǾǶεݹˣsolve + return b1 && b2 && (leftWeight * x->ll == rightWeight * x->rl); + +} + + + +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + + int n; + cin >> n; + string tmp; + getline(cin, tmp); // ȡһкĻ + + for (int i = 0; i < n; i++) { + mobile* root = nullptr; + bool ok = solve(root); + cout << (ok ? "YES" : "NO") << "\n"; + + if (i != n - 1) cout << "\n"; // ѯ֮һ + } + /* + for(int i = 0; i < n - 1; i++){ + cin >> a >> b >> c >> d; + mobile* tmp = new mobile(a, b, c, d); + if(a && !b){ + + } + } + DzõģӦȻȻγһ + */ + + return 0; +} diff --git a/Algorithm/Recursion/readme.md b/Algorithm/Recursion/readme.md new file mode 100644 index 0000000..bf7250c Binary files /dev/null and b/Algorithm/Recursion/readme.md differ