classSolution { public: boolprimeSubOperation(vector<int>& nums){ int n = nums.size(); int m = *max_element(nums.begin(), nums.end()); vector<int> prime; vector<bool> vis(m + 1, false); for (int i = 2; i <= m; i++) { if (!vis[i]) { prime.emplace_back(i); for (int j = i; j <= m; j += i) { vis[j] = true; } } } int pre = 0; for (int i = 0; i < n; i++) { auto it = lower_bound(prime.begin(), prime.end(), nums[i] - pre); if (it == prime.begin()) { if (nums[i] <= pre) { returnfalse; } } else { it--; nums[i] -= *it; } pre = nums[i]; } returntrue; } };
6357. 使数组元素全部相等的最少操作次数
给你一个正整数数组 nums 。
同时给你一个长度为 m 的整数数组 queries 。第 i 个查询中,你需要将 nums 中所有元素变成 queries[i] 。你可以执行以下操作 任意 次:
classSolution { public: vector<longlong> minOperations(vector<int>& nums, vector<int>& queries){ int n = nums.size(); int m = queries.size(); vector<longlong> res(m); sort(nums.begin(), nums.end()); vector<longlong> sum(n + 1); for (int i = 0; i < n; i++) { sum[i + 1] = sum[i] + nums[i]; } for (int i = 0; i < m; i++) { auto it = upper_bound(nums.begin(), nums.end(), queries[i]); int x = it - nums.begin(); res[i] = (longlong)x * queries[i] + sum[n] - 2 * sum[x] - (longlong)(n - x) * queries[i]; } return res; } };
6356. 收集树中金币
给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 。给你整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间有一条边。再给你一个长度为 n 的数组 coins ,其中 coins[i] 可能为 0 也可能为 1 ,1 表示节点 i 处有一个金币。
classSolution { public: intcollectTheCoins(vector<int>& coins, vector<vector<int>>& edges){ int n = coins.size(); int m = edges.size(); vector<int> degree(n); vector<unordered_set<int>> adj(n);
for (auto v : edges) { int x = v[0], y = v[1]; adj[x].emplace(y); adj[y].emplace(x); degree[x]++; degree[y]++; }
/* 去掉所有不含金币的叶子节点*/ queue<int> qu; vector<bool> visit(n, false); for (int i = 0; i < n; i++) { if (degree[i] == 1 && coins[i] == 0) { qu.emplace(i); degree[i]--; } } while (!qu.empty()) { int curr = qu.front(); visit[curr] = true; qu.pop(); for (auto v : adj[curr]) { degree[v]--; if (degree[v] == 1 && coins[v] == 0) { qu.emplace(v); } } }
/* 再次拓扑排序,去掉最外面的两层 */ for (int i = 0; i < n; i++) { if (degree[i] == 1 && coins[i] == 1) { qu.emplace(i); degree[i]--; visit[i] = true; } } for (int i = 0; i < 2; i++) { int sz = qu.size(); for (int j = 0; j < sz; j++) { int curr = qu.front(); visit[curr] = true; qu.pop(); for (auto v : adj[curr]) { degree[v]--; if (degree[v] == 1) { qu.emplace(v); } } } } int tot = 0; /* 统计未访问过的节点即可*/ for (int i = 0; i < n; i++) { if (!visit[i]) { tot++; } } return tot == 0 ? 0 : (tot - 1) * 2; } };