爪哇周赛 Round 1
A 第一场爪哇周赛
题目:oj | 第一场爪哇周赛
思路:
输出AC
代码:
C++
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "AC";
return 0;
}
B gq的图书馆之旅
题目:oj | gq的图书馆之旅
思路:
遍历取最大值,注意数据范围,注意要开long long,同时要注意max的初始化
代码:
C++
cpp
#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++
cpp
#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 做模 2 bits=8 2^{\text{bits=8}} 2bits=8(也就是取 n & (2^bits-1)),或者等价地:在原码上除符号位外取反加 1。
代码:
C++
cpp
#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语言
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++
cpp
#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++
cpp
#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;
}