lc749.dfs+simulate
通过设计数组记录,来进行大模拟
lc1806
模拟
math angel:可以用欧拉函数和费马小定理
class Solution {
public:
int reinitializePermutation(int n) {
vector<int> perm(n);
iota(perm.begin(), perm.end(), 0);
int operations = 0;
bool flag = false;
while (!flag) {
operations++;
vector<int> arr(n);
for (int i = 0; i < n; i++) {
if (i % 2 == 0) {
arr[i] = perm[i / 2];
} else {
arr[i] = perm[n / 2 + (i - 1) / 2];
}
}
perm = arr;
flag = isInitial(perm);
}
return operations;
}
bool isInitial(vector<int> perm) {
int n = perm.size();
for (int i = 0; i < n; i++) {
if (perm[i] != i) {
return false;
}
}
return true;
}
};
lc787.
图论的记忆化搜索
class Solution {
private:
unordered_map<int, vector<pair<int, int>>> e;
int memo[101][101]; // 假设n和k不超过100
int dst;
int k_max;
const int INF = INT_MAX / 2; // 避免溢出
int dfs(int u, int cnt) {
if (cnt > k_max + 1) {
return INF;
}
if (u == dst) {
return 0;
}
if (memo[u][cnt] != -1) {
return memo[u][cnt];
}
int ans = INF;
for (auto &edge : e[u]) {
int v = edge.first;
int w = edge.second;
ans = min(ans, dfs(v, cnt + 1) + w);
}
memo[u][cnt] = ans;
return ans;
}
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
// 构建邻接表
for (auto &f : flights) {
int from = f[0];
int to = f[1];
int weight = f[2];
e[from].emplace_back(to, weight);
}
// 初始化记忆化数组
memset(memo, -1, sizeof(memo));
this->dst = dst;
this->k_max = k;
// 计算结果
int ans = dfs(src, 0);
return ans < INF ? ans : -1;
}
};
lc2101
引爆:建有向图+bfs
找出一系列炸弹中,引爆其中某一颗时能连锁引爆的最大数量。
步骤:
1. 建关系网:先判断每两颗炸弹之间的距离,如果距离小于其中A炸弹的半径,就记为“A能引爆B”,用一个网络(图)记录这种关系。有向图
2. 逐个试爆:对每一颗炸弹,模拟引爆它,然后用“广度优先搜索”(类似一层层扩散)统计能连锁引爆多少颗。
3. 找最大值:记录所有试爆中能引爆的最大数量,就是结果。
简单说就是:先搞清楚“谁能引爆谁”,再挨个试,看哪颗能炸得最多。
class Solution {
public:
int maximumDetonation(vector<vector<int>>& bombs) {
int n = bombs.size();
vector<int> g[n];
for (int i = 0; i < n - 1; ++i) {
for (int j = i + 1; j < n; ++j) {
auto& p1 = bombs[i];
auto& p2 = bombs[j];
auto dist = hypot(p1[0] - p2[0], p1[1] - p2[1]);
if (dist <= p1[2]) {
g[i].push_back(j);
}
if (dist <= p2[2]) {
g[j].push_back(i);
}
}
}
int ans = 0;
bool vis[n];
for (int k = 0; k < n; ++k) {
memset(vis, false, sizeof(vis));
queue<int> q;
q.push(k);
vis[k] = true;
int cnt = 0;
while (!q.empty()) {
int i = q.front();
q.pop();
++cnt;
for (int j : g[i]) {
if (!vis[j]) {
vis[j] = true;
q.push(j);
}
}
}
if (cnt == n) {
return n;
}
ans = max(ans, cnt);
}
return ans;
}
};