爪哇周赛 Round 1
比赛链接
爪哇周赛 Round 1
A 第一场爪哇周赛
题目:oj | 第一场爪哇周赛
思路:
输出AC
代码:
C++
#include <bits/stdc++.h>
using namespace std;int main() {cout << "AC";return 0;
}
B gq的图书馆之旅
题目:oj | gq的图书馆之旅
思路:
遍历取最大值,注意数据范围,注意要开long long,同时要注意max的初始化
代码:
C++
#include <bits/stdc++.h>
using namespace std;int main() {int n;cin >> n;long long maxx = -100000000000;for (int i=0;i<n;i++) {long long a;cin >> a;maxx = max(a,maxx);}cout << maxx;return 0;
}
C 漂亮平均数
题目:oj | 漂亮平均数
思路:
可以证明最大的任意子数组平均值就是数组a的最大值,故遍历取最大值即可
代码:
C++
#include <bits/stdc++.h>
using namespace std;int main() {int t;cin >> t;while (t--) {int n;cin >> n;int maxx = -1;while (n--) {int x;cin >> x;maxx = max(maxx,x);}cout << maxx << "\n";}return 0;
}
D 二进制密码
题目:oj | 二进制密码
思路:
理解要点(简短)
- 正数的补码就是其原码(按二进制表示)。
- 负数的补码等于在相应固定位宽下对 n 做模 2bits=82^{\text{bits=8}}2bits=8(也就是取 n & (2^bits-1)),或者等价地:在原码上除符号位外取反加 1。
代码:
C++
#include <bits/stdc++.h>
using namespace std;string two_complement(int n, int bits = 8) {int minv = -(1 << (bits-1));int maxv = (1 << (bits-1)) - 1;int mask = (bits == 64) ? 0 : ((1 << bits) - 1);int val = n & mask;string s;for (int i = bits-1; i >= 0; --i) {s.push_back( (val >> i) & 1 ? '1' : '0' );}return s;
}void test(int n){string s = two_complement(n);cout << s << "\n";
}int main() {int n;cin>>n;test(n);return 0;
}
E 严厉的小红
题目:oj | 严厉的小红
思路:
tag:模拟
手上有五张牌,可能是打击,也可能是防御
由于题目只问当前回合是否能存活,所以只需要全出打击,或者说全出防御即可
于是就计算:当前回合,最多能打多少(能不能打死小红) 或者 最多能防多少(能不能防住这一轮攻击)
代码:
c语言
#include <stdio.h>
#include <string.h>void solve() {int red_blood, red_attack, my_blood;char vulnerable[4]; // 存储"yes"或"no",最多3个字符+结束符char cards[5][8]; // 存储5张手牌,最长"Defend"为7个字符+结束符// 读取第一行:小红血量、攻击、健仙血量scanf("%d %d %d", &red_blood, &red_attack, &my_blood);// 读取第二行:易伤状态scanf("%s", vulnerable);// 读取第三行:5张手牌for (int i = 0; i < 5; i++) {scanf("%s", cards[i]);}// 统计最多3张打击的总伤害(a)和最多3张防御的总格挡(b)int a = 0, b = 0;for (int i = 0; i < 5; i++) {if (strcmp(cards[i], "Strike") == 0) {a = (a + 6 > 18) ? 18 : a + 6; // 最多3张,总伤害≤18} else if (strcmp(cards[i], "Defend") == 0) {b = (b + 5 > 15) ? 15 : b + 5; // 最多3张,总格挡≤15}}// 处理易伤状态:伤害增加25%,向下取整if (strcmp(vulnerable, "yes") == 0) {red_attack = red_attack * 5 / 4; // 等价于×1.25后向下取整}// 判断生死:全防御挡不住且全攻击打不死 → 死亡if (b + my_blood <= red_attack && a < red_blood) {printf("cai jiu duo lian\n");} else {printf("lucky\n");}
}int main() {int T;scanf("%d", &T); // 读取测试用例数while (T--) {solve(); // 处理每组数据}return 0;
}
C++
#include <bits/stdc++.h>
using namespace std;void solve() {int blood, attack, myblood;string s;cin >> blood >> attack >> myblood >> s;int a = 0, b = 0;for (int i = 0; i < 5; i++) {string card; cin >> card;if (card == "Strike") a = min(a + 6, 18);if (card == "Defend") b = min(b + 5, 15);}int flag = 0;if (s == "yes") flag = 1;if (flag) attack = attack * 5 / 4;if (b + myblood <= attack && a < blood) {cout << "cai jiu duo lian" << endl;}else {cout << "lucky" << endl;}
}int main() {int _ = 1;cin >> _;while (_--) solve();return 0;
}
F 前三名
题目:oj | 前三名
思路:
本题必须保证O(1)空间复杂度。核心想法很简单:用三个变量分别记录目前找到的 “第一名”“第二名”“第三名”,然后逐个读取成绩,不断更新这三个变量。就像比赛打分时,裁判手里记着当前的前三名,来了一个新分数,就看看能不能挤掉现有的前三名,再重新排序。
详细步骤
先准备三个 “容器”:first(第一大)、second(第二大)、third(第三大),初始都设为 0。读入成绩的总数量n。逐个读入每个成绩x,并判断:
-
如果x比当前的first还大,说明x是新的第一名,原来的第一名退为第二名,原来的第二名退为第三名。
-
如果x没超过first,但比second大,说明x是新的第二名,原来的第二名退为第三名。
-
如果x没超过second,但比third大,说明x是新的第三名。
所有成绩读完后,输出这三个变量就是前三大的成绩。
本题也可用优先队列解决,始终保持队列里只有当前最大的 3 个元素,最后直接取出这 3 个元素即可
代码:
C++
#include <iostream>
using namespace std;int main() {ios::sync_with_stdio(false);//数据量大,cpp需要优化输入输出cin.tie(nullptr);cout.tie(nullptr);int n;cin >> n;int first = 0, second = 0, third = 0, x;for (int i = 0; i < n; ++i) {cin >> x;if (x > first) {third = second;second = first;first = x;} else if (x > second) {third = second;second = x;} else if (x > third) {third = x;}}cout << first << " " << second << " " << third << endl;return 0;
}