1004 战争游戏
根据题目条件建树,记树的直径长为 d。
- 如果
,那么进攻方只需要选择直径的终点就可以获胜
- 如果
并且
,进攻方可以将防守方一步一步逼向叶子节点最后获胜
- 如果
并且
,防守方永远可以逃出轰炸范围,防守方获胜
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int t, n, s, r1, r2, u, v, dis[N], len, id;
vector<vector<int>> e(N);
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
void dfs(int u, int fa) {
dis[u] = dis[fa] + 1;
for (int v : e[u]) {
if (v != fa) dfs(v, u);
}
return;
}
int main() {
t = read();
while (t--) {
n = read(), s = read(), r1 = read(), r2 = read();
for (int i = 1; i < n; i++) {
u = read(), v = read();
e[u].push_back(v), e[v].push_back(u);
}
dfs(1, 0); // 任选一个节点进行遍历,记录剩余节点距离当前节点的距离
id = 1, len = 0;
for (int i = 2; i <= n; i++) if (dis[i] > dis[id]) id = i;
// 找到距离当前节点最远的节点的编号,该节点一定是直径的一个端点
dfs(id, 0); // 从直径的一个端点进行遍历,记录其他节点到这个端点的距离
for (int i = 1; i <= n; i++) len = max(len, dis[i]);
// 距离直径一个端点最远的节点就是直径的另一个端点
// 两个节点之间的距离就是直径长度
if (2 * r1 + 1 >= len) puts("Kangaroo_Splay");
else {
if (2 * r1 >= r2) puts("Kangaroo_Splay");
else puts("General_Kangaroo");
}
for (int i = 1; i <= n; i++) e[i].clear();
}
return 0;
}
1010 故障机器人想活下去
从头开始遍历敌人,将前 k 大的 存入一个优先队列里面,记录剩余的
的和 res,当
的时候,输出 i - 1;如果能战胜全部敌人,则输出 n。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
int n, x, k, a[N];
priority_queue<int, vector<int>, greater<int>> q;
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
void solve() {
n = read(), x = read(), k = read();
for (int i = 1; i <= n; i++) a[i] = read();
int ans = 0, res = 0;
while (!q.empty()) q.pop();
for (int i = 1; i <= n; i++) {
if (q.size() < k) {
q.push(a[i]);
} else {
if (!q.empty() && q.top() < a[i]) {
res += q.top();
q.pop();
q.push(a[i]);
} else {
res += a[i];
}
}
if (res >= x) {
printf("%lld\n", i - 1);
return;
}
}
printf("%lld\n", n);
return;
}
signed main() {
int t = read();
while (t--) {
solve();
}
return 0;
}
1011 蛋糕上的草莓是蛋糕的灵魂
为了优先保证每个草莓的大小最大,再保证每个蛋糕的大小最大,要在满足草莓数量尽可能少的前提下,让蛋糕尽可能地少。
- 蛋糕不需要进行切割
最终草莓的数量一定是蛋糕的正整数倍,如果切割后的蛋糕都能满足条件,那么切割前的蛋糕也一定能满足条件
- 草莓的数量一定是 x,y 的最小公倍数
或者是 x,y 的最小公倍数的两倍
记 m,n 的最小公倍数为 。由于最终草莓的数量一定是蛋糕的正整数倍,草莓的数量一定是
或其正整数倍,并且切割后的草莓一定是原来的偶数倍,
- 当
是 x 的奇数倍时,x 无法切割成
个,只能切割成
个
- 当
时 x 的偶数倍时,x 可以切割成
个
- 当 x 正好是 y 的倍数时,不需要切割
#include <bits/stdc++.h>
using namespace std;
#define int long long
int x, y;
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int gcd(int a, int b) { return a == 0 ? b : gcd(b % a, a); }
signed main() {
int t = read();
while (t--) {
x = read(), y = read();
int tar = gcd(x, y), tar2 = y / tar;
if(tar2 == 1 || tar2 % 2 == 0) printf("%lld %lld\n", y, x / tar);
else printf("%lld %lld\n", y, x / tar * 2);
}
return 0;
}