I. This is an easy problem
题目大意
给你一个数问二进制下有多少个1
解题思路
直接转二进制统计即可
代码实现
print(bin(int(input())).count("1"))
B. String
题目大意
给一个字符串,存在三个相同字符就可以删去,问字符串最后的结果是什么
解题思路
按题意模拟即可
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int siz = 0;
std::string s, ans;
std::cin >> s;
for (auto ch : s) {
ans += ch;
siz++;
while (siz >= 3 && ans[siz - 1] == ans[siz - 2] && ans[siz - 1] == ans[siz - 3]) {
ans.pop_back();
ans.pop_back();
ans.pop_back();
siz -= 3;
}
}
if (ans.empty()) {
std::cout << "NAN\n";
} else {
std::cout << ans << "\n";
}
}
K. Puzzle
题目大意
给你四个数,可以在±*中选三个符号,求能有多少种不同的结果
解题思路
只有四个数三种符号全排列暴力统计即可
代码实现
import itertools
print(len(set([eval(f'{i[0]}{j[0]}{i[1]}{j[1]}{i[2]}{j[2]}{i[3]}') for i in list(itertools.permutations(list(map(int, input().split())), 4)) for j in list(itertools.permutations("+++---***", 3))])))
J. Trade
题目大意
给你两个n*m的矩阵ab, a [ x ] [ y ] a[x][y] a[x][y]表示商品在此地的售价, b [ x ] [ y ] b[x][y] b[x][y]表示到此地的路费,一开始在(1,1)有一个商品,要求从(1,1)出发只能向右下走,到最后一行或者最后一列结束,问是否有路线满足在路线上任意一个位置出售商品,利润始终非负,利润计算公式为 a [ x t ] [ y t ] − a [ 1 ] [ 1 ] − ∑ i = 1 t b [ x i ] [ y i ] a[x_t][y_t]-a[1][1]-\sum_{i=1}^{t} b[x_i][y_i] a[xt][yt]−a[1][1]−∑i=1tb[xi][yi]
解题思路
dp计算出每一个位置的利润,再bfs搜索非负的位置判断能不能到边界
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n, m;
std::cin >> n >> m;
std::vector<std::vector<i64>> a(n + 1, std::vector<i64>(m + 1)), b(n + 1, std::vector<i64>(m + 1, INT_MAX)), vis(n + 1, std::vector<i64>(m + 1));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
std::cin >> a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
std::cin >> b[i][j];
}
}
int x = a[1][1];
b[0][1] = b[1][0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
b[i][j] += std::min(b[i - 1][j], b[i][j - 1]);
a[i][j] -= b[i][j] + x;
}
}
std::queue<std::array<i64, 3>> q;
q.push({1, 1, 1});
while (!q.empty()) {
auto [x, y, _] = q.front();
q.pop();
if (x == n || y == m) {
std::cout << "YES\n";
return 0;
}
if (x + 1 <= n && a[x + 1][y] >= 0 && !vis[x + 1][y]) {
q.push({x + 1, y, a[x + 1][y]});
vis[x + 1][y] = 1;
}
if (y + 1 <= m && a[x][y + 1] >= 0 && !vis[x][y + 1]) {
q.push({x, y + 1, a[x][y + 1]});
vis[x][y + 1] = 1;
}
}
std::cout << "NO\n";
}
D. Card Game
题目大意
两个玩家ab在玩卡牌游戏,给定双方的血量,每张攻击牌的攻击力和防御牌(可以抵挡一次任意攻击),问a能否获胜
解题思路
换血阶段显然a出攻击力高的牌,b出攻击力低的牌最优,相当于a是不需要防御的(进攻是最好的防守),并且a必须在这个阶段就取得游戏胜利(平局就是a没赢),因此可以认为对b来说防御牌是一张无限攻击力的牌,然后对a牌降序b牌升序,一直换血直到有一方战败
代码实现
#include <bits/stdc++.h>
using i64 = long long;
const i64 INF = 4e18;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
i64 n, hpa, hpb;
std::cin >> n >> hpa >> hpb;
std::vector<i64> A, B;
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
if (x != -1) {
A.push_back(x);
}
}
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
if (x == -1) {
B.push_back(INF);
} else {
B.push_back(x);
}
}
std::sort(A.begin(), A.end(), std::greater<i64>());
std::sort(B.begin(), B.end());
int i = 0, j = 0;
while (hpa > 0 && hpb > 0 && i < A.size() && j < B.size()) {
hpb -= A[i];
hpa -= B[j];
i++;
j++;
}
if (hpa > 0 && hpb <= 0) {
std::cout << "yes\n";
} else {
std::cout << "no\n";
}
}
}
F. Photography
题目大意
给定一张n点m边的无向图,每个点都有点权,要求最大化五个联通的点权之和
解题思路
正解是先预处理每一个点最大的三个邻接点然后暴力枚举链的两端找第五个点,但是直接枚举五个点加上一些剪枝暴力dfs好像也跑的飞快
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
i64 n, m, ans = 0;
std::cin >> n >> m;
std::vector<int> a(n + 1), vis(n + 1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
std::vector<std::vector<int>> g(n + 1);
for (int i = 0; i < m; i++) {
int u, v;
std::cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
std::sort(g[i].begin(), g[i].end(), [&](int x, int y) { return a[x] > a[y]; });
}
std::vector<i64> b(a.begin() + 1, a.end()), pre(6);
std::sort(b.rbegin(), b.rend());
for (int i = 1; i <= 5; i++) {
if (i - 1 < b.size()) {
pre[i] = pre[i - 1] + b[i - 1];
} else {
pre[i] = pre[i - 1];
}
}
auto dfs = [&](auto &&self, int u, int fa, int cnt, i64 x) -> void {
cnt++;
x += a[u];
ans = std::max(ans, x);
if (cnt == 5 || x + pre[5 - cnt] <= ans) {
return;
}
vis[u] = 1;
for (auto v : g[u]) {
if (v != fa && !vis[v]) {
self(self, v, u, cnt, x);
}
}
vis[u] = 0;
};
for (int i = 1; i <= n; i++) {
dfs(dfs, i, -1, 0, 0);
}
std::cout << ans << "\n";
}