diff --git a/Algorithm/Divide&Conquer/最大连续和.cpp b/Algorithm/Divide&Conquer/最大连续和.cpp new file mode 100644 index 0000000..d4e04ed --- /dev/null +++ b/Algorithm/Divide&Conquer/最大连续和.cpp @@ -0,0 +1,14 @@ +#include +#include +using namespace std; +//ȫߣȫұߣԽм +vector arr; + +int dfs(int l, int r){ + +} + +int main(){ + + return 0; +} diff --git a/Algorithm/IterativeDeepening/Egypt-Fraction-AI-BAD.cpp b/Algorithm/IterativeDeepening/Egypt-Fraction-AI-BAD.cpp new file mode 100644 index 0000000..46f1e98 --- /dev/null +++ b/Algorithm/IterativeDeepening/Egypt-Fraction-AI-BAD.cpp @@ -0,0 +1,63 @@ +#include +using namespace std; + +vector best_solution; // ǰŽ +int best_max_den = INT_MAX; // ǰŽĸ + +// gcd +long long gcd(long long a, long long b) { + return b == 0 ? a : gcd(b, a % b); +} + +// DFS +void dfs(vector& path, int step, int max_depth, + long long num, long long den, int a, int b, int start) { + if(step > max_depth) return; + + if(num * b == den * a) { + int cur_max = *max_element(path.begin(), path.end()); + if(best_solution.empty() || cur_max < best_max_den) { + best_solution = path; + best_max_den = cur_max; + } + return; + } + + // ޼֦ + long long i_start = max((long long)start, (den + num - 1) / num); // ceil(den/num) + for(long long i = i_start; i <= 15000; i++) { + path.push_back(i); + long long new_num = num * i + den; + long long new_den = den * i; + long long g = gcd(new_num, new_den); + new_num /= g; + new_den /= g; + if(new_num * b <= new_den * a) { // ֦ + dfs(path, step + 1, max_depth, new_num, new_den, a, b, i + 1); + } + path.pop_back(); + } +} + +// IDS +vector egyptian_fraction(int a, int b) { + best_solution.clear(); + best_max_den = INT_MAX; + + for(int depth = 1; depth <= 15000; depth++) { // ȿɵ + vector path; + dfs(path, 0, depth, 0, 1, a, b, 1); + if(!best_solution.empty()) break; // ҵ̳Ƚ + } + return best_solution; +} + +int main() { + int a, b; + cin >> a >> b; + vector res = egyptian_fraction(a, b); + for(int x : res) cout << x << " "; + cout << endl; + return 0; +} + diff --git a/Algorithm/IterativeDeepening/Egypt-Fraction-AI.cpp b/Algorithm/IterativeDeepening/Egypt-Fraction-AI.cpp new file mode 100644 index 0000000..21a9331 --- /dev/null +++ b/Algorithm/IterativeDeepening/Egypt-Fraction-AI.cpp @@ -0,0 +1,143 @@ +#include + +using namespace std; + +typedef long long ll; // ʹ long long Դϴķĸ + +// ԼGCDԼַ +ll gcd(ll a, ll b) { + return b == 0 ? a : gcd(b, a % b); // շת +} + +// n/d ԼΪʽ +pair reduce(ll n, ll d) { + ll g = gcd(abs(n), d); // n d GCDabs(n) ֹ + return {n / g, d / g}; // ԼֺķӺͷĸ +} + +// ʾ״̬Ľṹ +struct State { + ll num, den; // ǰʣ num/den + vector dens; // ѡĵλķĸб + + // 㵱ǰ״̬ĸ + ll max_den() const { + if (dens.empty()) return 0; // ûзĸ 0 + return *max_element(dens.begin(), dens.end()); // طĸбеֵ + } +}; + +// ϣ unordered_set д洢״̬ʵδʹãԱչ +struct StateHash { + size_t operator()(const State& s) const { + string str; + for (ll x : s.dens) str += to_string(x) + ","; + str += to_string(s.num) + "/" + to_string(s.den); + return hash()(str); + } +}; + +// ȡǰ״̬к״̬ +vector get_successors(const State& state, int limit, int depth) { + vector res; // 洢пܵĺ״̬ + ll r = state.num, s = state.den; // ǰʣ r/s + if (r == 0) return res; // Ϊ 0չ + + // ȷСĸһĸ֤ĸظ r/s >= 1/d + ll last_d = state.dens.empty() ? 0 : state.dens.back(); + ll min_d = max(last_d + 1, (s + r - 1) / r); // min_d = ceil(s/r) + + // ÷ĸޣֹķĸ¼ + const ll MAX_D = 10000000LL; // İȫ + + // öٿܵĵλĸ d + for (ll d = min_d; d <= MAX_D; ++d) { + // ŻʣಽǷ㹻ʾʣ + int rem_steps = limit - depth - 1; // ʣò + double max_sum_after = 0.0; // ʣಽܱʾ + for (int i = 1; i <= rem_steps; ++i) { + max_sum_after += 1.0 / (d + i); // ĸ + } + double this_contrib = 1.0 / d; // ǰλĹ + double target = (double)r / s; // Ŀʣ + // ǰ׼ϺܹСĿ֦꣬ + if (this_contrib + max_sum_after < target - 1e-10) break; + + // ·r/s - 1/d = (r*d - s) / (s*d) + ll new_num = r * d - s; + if (new_num < 0) continue; // ·ΪǷ״̬ + ll new_den = s * d; + auto p = reduce(new_num, new_den); // Լ· + State ns = {p.first, p.second, state.dens}; // ״̬ + ns.dens.push_back(d); // ӵǰλĸ + res.push_back(ns); // ״̬б + } + return res; +} + +// DFSڵǰ +void dfs(const State& state, int depth, int limit, vector& solutions) { + if (depth > limit) return; // ƣ + if (state.num == 0 && !state.dens.empty()) { // ҵһ⣺Ϊ 0 һĸ + solutions.push_back(state); // ¼ + return; // չ· + } + // к״̬ + for (const auto& next : get_successors(state, limit, depth)) { + dfs(next, depth + 1, limit, solutions); // ݹ + } +} + +// IDSѰ̳ĸСİ +State find_best_egyptian(ll a, ll b) { + auto p = reduce(a, b); // Լ + State start = {p.first, p.second, {}}; // ʼ״̬ + State best; // ¼ѽ + ll best_max = LLONG_MAX; // ѽĸ + int limit = 0; // ǰ + + while (true) { + ++limit; // + vector solutions; // 洢ǰµн + dfs(start, 0, limit, solutions); // ִ DFS + if (!solutions.empty()) { // ҵ + for (const auto& s : solutions) { // н + ll cur_max = s.max_den(); // ǰĸ + if (cur_max < best_max) { // ĸСѽ + best = s; + best_max = cur_max; + } + } + return best; // ѽ + } + if (limit > 100) { // ȫƣֹѭ + cout << "No solution found within limit." << endl; + exit(1); + } + } +} + +int main() { + ll a, b; + // ӺͷĸҪ 0 < a < b һ + cout << "Enter numerator and denominator (a b, with 0 < a < b, gcd=1): "; + cin >> a >> b; + if (a >= b || a <= 0 || gcd(a, b) != 1) { // ֤ + cout << "Invalid input: require 0 < a < b and gcd(a,b)=1" << endl; + return 1; + } + + State result = find_best_egyptian(a, b); // ѰѰ + + // + cout << a << "/" << b << " = "; + for (size_t i = 0; i < result.dens.size(); ++i) { + if (i > 0) cout << " + "; + cout << "1/" << result.dens[i]; // ӡλ + } + cout << endl; + cout << "Length: " << result.dens.size() << endl; // ӡֽⳤ + cout << "Max denominator: " << result.max_den() << endl; // ӡĸ + + return 0; +} diff --git a/Algorithm/IterativeDeepening/Egypt-Fraction-AI.exe b/Algorithm/IterativeDeepening/Egypt-Fraction-AI.exe new file mode 100644 index 0000000..e7c9980 Binary files /dev/null and b/Algorithm/IterativeDeepening/Egypt-Fraction-AI.exe differ diff --git a/Algorithm/IterativeDeepening/Egypt-Fraction-BAD.cpp b/Algorithm/IterativeDeepening/Egypt-Fraction-BAD.cpp new file mode 100644 index 0000000..dabdcd0 --- /dev/null +++ b/Algorithm/IterativeDeepening/Egypt-Fraction-BAD.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +using namespace std; +// f = a/b +double checkv(const vector& x){ + double c = 0.0; + for(auto q : x){ + c += 1.0 / q; + } + return c; + //return fabs(c - r) < 1e-9; // ƱȽ +} + +//stepΪ־ +bool dfs(vector& path, int step, int max_depth, int a, int b, int max_val){ + double r = static_cast(a) / b; + if(fabs(checkv(path) - r) < (1e-9)){ + for(int x : path) cout << x << " "; + cout << endl; + return true; + } + if(checkv(path) > r + (1e-9)) return false; + if(step == max_depth) return false; + + int start = path.empty() ? 1 : path.back(); + for(int i = start; i <= max_val; i++){ + path.push_back(i); + if(dfs(path, step + 1, max_depth, a, b, max_val)) return true; + path.pop_back(); + } + return false; +} + +bool ids(int limit, int a, int b, int max_val){ + for(int depth = 1; depth <= limit; depth++){ + vector path; + if(dfs(path, 0, depth, a, b, max_val)) return true; + } + return false; +} + +int main(){ + int aa, bb, max; + cin >> aa >> bb; + max = 200; + ids(10, aa, bb, max); + return 0; +} diff --git a/Algorithm/IterativeDeepening/readme.md b/Algorithm/IterativeDeepening/readme.md new file mode 100644 index 0000000..ca09ce0 --- /dev/null +++ b/Algorithm/IterativeDeepening/readme.md @@ -0,0 +1,15 @@ +🔹 基本思想 + +广度优先搜索 (BFS):逐层扩展,能保证找到最优解,但需要大量内存。 + +深度优先搜索 (DFS):沿一条路径搜索下去,内存消耗小,但可能陷入深层无解分支,不能保证最优解。 + +**迭代加深搜索 (IDS) 的做法是:** + +设定一个最大搜索深度限制(depth limit),先用 DFS 在这个深度内搜索。 + +如果没找到解,就把深度限制增加 1,再次用 DFS 搜索。 + +重复以上过程,直到找到目标或达到全局深度上限。 + +> 重点是树没有上限的情况->棋类竞技 \ No newline at end of file diff --git a/std-Cpp/BitWiseOperation/readme.md b/std-Cpp/BitWiseOperation/readme.md new file mode 100644 index 0000000..71005a4 --- /dev/null +++ b/std-Cpp/BitWiseOperation/readme.md @@ -0,0 +1,100 @@ +好嘞 👍 你问到的 **C++ 位运算符**,其实是底层操作里最常用的一类。它们直接对整数的**二进制位**进行操作,比算术运算更接近硬件。 + +--- + +## 🔑 C++ 位运算符总览 + +| 运算符 | 名称 | 含义 | 示例(假设 `a = 6 (0110₂)`, `b = 11 (1011₂)`) | 结果 | | +| --------------- | ---------- | ------------------------------------------------ | ---------------------------------------- | ----------- | -- | +| `&` | 按位与 (AND) | 对应位都为 1 才为 1 | `a & b = 0010₂` | 2 | | +| \| | 按位或 (OR) | 对应位至少一个为 1 就为 1 | \`a | b = 1111₂\` | 15 | +| `^` | 按位异或 (XOR) | 对应位相同为 0,不同为 1 | `a ^ b = 1101₂` | 13 | | +| `~` | 按位取反 (NOT) | 0 变 1,1 变 0 | `~a = ...11111001₂` | -7(补码表示) | | +| `<<` | 左移 | 所有二进制位向左移,右边补 0 | `a << 1 = 1100₂` | 12 | | +| `>>` | 右移 | 所有二进制位向右移,左边补符号位(算术右移)或 0(逻辑右移,C++ 对有符号数实现依赖编译器) | `a >> 1 = 0011₂` | 3 | | + +--- + +## 📘 详细解释 + +### 1. 按位与 `&` + +常用来 **取某些位**: + +```cpp +int x = 13; // 1101₂ +int mask = 4; // 0100₂ +if (x & mask) cout << "第3位是1" << endl; // 输出 第3位是1 +``` + +### 2. 按位或 `|` + +常用来 **设置某些位为 1**: + +```cpp +int x = 5; // 0101₂ +int mask = 2; // 0010₂ +x = x | mask; // 0111₂ -> 7 +``` + +### 3. 按位异或 `^` + +* 不同为 1,相同为 0。 +* 特性:`a ^ a = 0`,`a ^ 0 = a`。 +* 常用于 **交换变量** 或 **求对称差**。 + +```cpp +int a = 5, b = 9; +a = a ^ b; +b = a ^ b; +a = a ^ b; +cout << a << " " << b << endl; // 输出 9 5 +``` + +### 4. 按位取反 `~` + +逐位取反。注意负数结果与补码有关: + +```cpp +int a = 6; // 0000...0110 +cout << ~a << endl; // -7 +``` + +### 5. 左移 `<<` + +相当于乘以 $2^n$(但可能溢出): + +```cpp +int a = 3; // 0011₂ +cout << (a << 2) << endl; // 1100₂ = 12 +``` + +### 6. 右移 `>>` + +相当于整除 $2^n$(但要区分有符号/无符号): + +```cpp +int a = 12; // 1100₂ +cout << (a >> 2) << endl; // 0011₂ = 3 +``` + +--- + +## ⚡ 补充:常见用途 + +1. **快速运算**:`x << 1` 相当于 `x * 2`,`x >> 1` 相当于 `x / 2`。 +2. **掩码操作**:取某些位、清零某些位、设置某些位。 +3. **集合表示**:一个整数的二进制位可以看作集合的元素是否存在。 +4. **加密/压缩**:异或在流密码、校验和算法里很常见。 + +--- + +✅ **总结** + +* C++ 提供了 `& | ^ ~ << >>` 六个主要位运算符。 +* 它们直接操作二进制位,速度快、常用于底层优化。 +* 常见技巧:掩码操作、快速乘除、集合运算、加密。 + +--- + +要不要我帮你写一个 **完整的小程序**,输入两个整数,输出它们的二进制表示,以及 `& | ^ ~ << >>` 的运算结果?这样能直观看清效果。