呐呐呐~第一份随笔
2022/3/28 23:29:31
本文主要是介绍呐呐呐~第一份随笔,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Become an ACMer
算法被发明出来,是为了解决问题;而评价一个算法的好坏,在于它能否迅速、简洁、优雅地解决问题。
“保持一颗热爱的心。你也能够成功的吧。”
这是学习算法的初衷。相信自己吧。
PART 1 预备知识
<1>
我们常常需要(1)快读(2)重定向(3)打表(4)预处理 等等,这些都是对数据读写的处理。
(1)快读常用于读入数据量较多的 int, 它的原理由 getchar() 实现;
inline int read() { int s = 1, v = 0; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') s = -1; c = getchar(); } while (c >= '0' && c <= '9') { v = (v << 3) + (v << 1) + (c ^ 48); c = getchar(); } return s * v; }
(2)重定向常用于文件读写,它通过 freopen() 实现;
freopen("data.in", "r", stdin); freopen("data.out", "w", stdout);
(3)打表用于解决时间复杂度高且数据范围小的问题,将所有结果输出并记录在数组里;
(4)预处理是将一些可能会用到的数据提前处理并记录下来,便于以后调用,如埃氏筛、欧拉筛。
#include <bits/stdc++.h> using namespace std; const int N = 1e6; int n, cnt, a[N], p[N]; void Era() { for (int i = 2; i <= N; ++i) { if (!a[i]) p[cnt++] = i; for (int j = i; j <= N; j += i) a[j] = 1; } } int main() { cin >> n; Era(); cout << p[n]; }
点击查看代码
#include <bits/stdc++.h> using namespace std; const int N = 1e8; int n, cnt, a[N], p[N]; void Euler() { for (int i = 2; i <= N; ++i) { if (!a[i]) p[cnt++] = i; for (int j = 0; j < cnt; j++) { if (i * p[j] > N) break; a[i * p[j]] = true; if (i % p[j] == 0) break; } } } int main() { cin >> n; Euler(); cout << p[n]; }
<2>
一些经典问题的解法是值得背诵的。
(1)八皇后(深度优先搜索,状态压缩)
#include <bits/stdc++.h> using namespace std; int N, cnt, b1[100], b2[100], b3[100]; void dfs(int n) { if (n > N) { cnt++; return; } for (int i = 1; i <= N; i++) if (b1[i] == 0 && b2[N - n + i] == 0 && b3[n + i] == 0) { b1[i] = 1, b2[N - n + i] = 1, b3[n + i] = 1; dfs(n + 1); b1[i] = 0, b2[N - n + i] = 0, b3[n + i] = 0; } } int main() { cin >> N; dfs(1); cout << cnt; }
点击查看代码
#include <bits/stdc++.h> using namespace std; unsigned long long res, k, n, cnt, num[1000], s[1000], f[10][300][300]; void init() { for (int i = 0; i < (1 << n); i++) { if (i & (i << 1)) continue; int sum = 0; for (int j = 1; j < (1 << n); j <<= 1) { if (j & i) sum++; } num[++cnt] = sum; s[cnt] = i; f[1][cnt][sum] = 1; } } void dp() { for (int i = 1; i <= n; i++) for (int j = 1; j <= cnt; j++) for (int r = 0; r <= k; r++) if (r >= num[j]) for (int q = 1; q <= cnt; q++) if (!(s[j] & s[q]) && !((s[j] << 1) & s[q]) && !((s[j] >> 1) & s[q])) f[i][j][r] += f[i - 1][q][r - num[j]]; for (int i = 1; i <= cnt; i++) res += f[n][i][k]; } int main() { cin >> n >> k; init(); dp(); cout << res; }
(2)迷宫(广度优先搜索)
#include <bits/stdc++.h> using namespace std; int n, m, sx, sy, ex, ey; int a[100][100], b[100][100], d[4][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}}; struct node { int x, y, step; }; queue<node> q; int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> a[i][j]; cin >> sx >> sy >> ex >> ey; q.push({sx, sy, 0}); while (!q.empty()) { int x = q.front().x, y = q.front().y, step = q.front().step; q.pop(); if (x == ex && y == ey) { cout << step; return 0; } for (int i = 0; i < 4; i++) { int tx = x + d[i][0], ty = y + d[i][1]; if (a[tx][ty] == 1 && b[tx][ty] == 0) { b[tx][ty] = 1; q.push({tx, ty, step + 1}); } } } cout << "-1"; }
(3)路标设置(二分法)
#include <bits/stdc++.h> using namespace std; const int N = 1e6; int l, n, k, ans, a[N]; bool check(int x) { int i = 1, cnt = 0; while (i < n) { int j = 1; while (a[i] - a[i - 1] > j * x) { cnt++; j++; } i++; } if (cnt <= k) return true; else return false; } int main() { cin >> l >> n >> k; for (int i = 0; i < n; i++) cin>>a[i]; int left = 1, right = l; while (left <= right) { int mid = (left + right) / 2; if (check(mid)) { right = mid - 1; ans = mid; } else left = mid + 1; } cout << ans; }
(4)背包(记忆化搜索,动态规划)
#include <bits/stdc++.h> using namespace std; int n, W, w[100], v[100], f[1000][1000]; int dfs(int i, int j) { if (f[i][j] >= 0) return f[i][j]; int res; if (i == n) res = 0; else if (j < w[i]) res = dfs(i + 1, j); else res = max(dfs(i + 1, j), dfs(i + 1, j - w[i]) + v[i]); return f[i][j] = res; } int main() { cin >> n; for (int i = 0; i < n; i++) cin >> w[i] >> v[i]; cin >> W; memset(f, -1, sizeof(f)); cout << dfs(0, W); }
点击查看代码
#include <bits/stdc++.h> using namespace std; int n, W, w[100], v[100], f[1000][1000]; int main() { cin >> n; for (int i = 0; i < n; i++) cin >> w[i] >> v[i]; cin >> W; for (int i = n - 1; i >= 0; i--) for (int j = 0; j <= W; j++) if (j < w[i]) f[i][j] = f[i + 1][j]; else f[i][j] = max(f[i + 1][j], f[i + 1][j - w[i]] + v[i]); cout << f[0][W]; }
(5)最小逆序对数(分治)
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 2e6 + 5; int t, n, m, tot, cnt; int a[N], b[N], c[N], d[N], A[N], p[N]; void disc() { sort(d + 1, d + 1 + tot); cnt = unique(d + 1, d + 1 + tot) - d - 1; for (int i = 1; i <= n; i++) a[i] = lower_bound(d + 1, d + 1 + cnt, a[i]) - d; for (int i = 1; i <= m; i++) b[i] = lower_bound(d + 1, d + 1 + cnt, b[i]) - d; } int lowbit(int x) { return x & (-x); } void upd(int x) { for (; x <= cnt; x += lowbit(x)) c[x]++; } ll qry(int x) { ll summ = 0; for (; x; x -= lowbit(x)) summ += c[x]; return summ; } ll calc() { ll summ = 0; for (int i = 1; i <= tot; i++) { summ += qry(cnt) - qry(A[i]); upd(A[i]); } return summ; } void solve(int Lb, int Rb, int La, int Ra) { if (Lb > Rb) return; int mid = (Lb + Rb) >> 1; int val = b[mid]; int minn = 2e9, summ1 = 0, summ2 = 0; for (int i = Ra - 1; i >= La; i--) { if (a[i] < val) summ2++; } minn = summ2; p[mid] = La; for (int i = La + 1; i <= Ra; i++) { if (a[i - 1] < val) summ2--; if (a[i - 1] > val) summ1++; if (summ1 + summ2 < minn) { minn = summ1 + summ2; p[mid] = i; } } solve(Lb, mid - 1, La, p[mid]); solve(mid + 1, Rb, p[mid], Ra); } int main() { cin >> t; while (t--) { tot = 0; cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i]; d[++tot] = a[i]; } for (int i = 1; i <= m; i++) { cin >> b[i]; d[++tot] = b[i]; } sort(b + 1, b + 1 + m); disc(); for (int i = 1; i <= cnt; i++) c[i] = 0; solve(1, m, 1, n + 1); tot = 0; int k = 1; for (int i = 1; i <= n; i++) { while (p[k] == i && k <= m) { A[++tot] = b[k]; k++; } A[++tot] = a[i]; } while (k <= m) { A[++tot] = b[k]; k++; } cout << calc(); } }
这篇关于呐呐呐~第一份随笔的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16ShardingSphere 如何完美驾驭分布式事务与 XA 协议?
- 2024-11-16ShardingSphere如何轻松驾驭Seata柔性分布式事务?
- 2024-11-16Maven资料入门指南
- 2024-11-16Maven资料入门教程
- 2024-11-16MyBatis Plus资料:新手入门教程与实践指南
- 2024-11-16MyBatis-Plus资料入门教程:快速上手指南
- 2024-11-16Mybatis资料入门教程:新手必看指南
- 2024-11-16MyBatis资料详解:新手入门与初级实战指南
- 2024-11-16MyBatisPlus资料:初学者入门指南与实用教程
- 2024-11-16MybatisPlus资料详解:初学者入门指南