A题:Leap Year
题意
判断闰年
思路
大水题
代码
#include <iostream>
using namespace std;
int main() {
int x; cin >> x;
int ans = 365 + (x % 4 == 0 && x % 100 != 0 || x % 400 == 0);
cout << ans << endl;
return 0;
}
B题:Second Best
题意
找到给定数组中第二大的数的位置
思路
sort一下即可
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using PII = pair<int, int>;
int main() {
int n; cin >> n;
vector<PII> a(n);
for (int i = 0; i < n; i ++ ) {
cin >> a[i].first;
a[i].second = i;
}
sort(a.begin(), a.end());
cout << a[n - 2].second + 1 << endl;
return 0;
}
C题:Transportation Expenses
题意
略
思路
明显的二分答案
代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
using ll = long long;
int main() {
ll n, m; cin >> n >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i ++ ) cin >> a[i];
ll l = -1, r = (ll)1e10;
function<bool(ll)> check = [&](ll x) {
ll sum = 0;
for (int i = 1; i <= n; i ++ ) sum += min(x, (ll)a[i]);
return sum <= m;
};
while (l + 1 != r) {
ll mid = l + r >> 1;
if (check(mid)) l = mid;
else r = mid;
}
if (l > 1e9) cout << "infinite" << endl;
else cout << l << endl;
return 0;
}
D题:AtCoder Janken 3
题意
石头剪刀布,高桥每局比赛不会失败,但他出的手型不能与上一次相同,问最大获胜次数
思路
贪心贪不对,那么可以简单写一个状态机
dp[3]到i为止,出0~2中可以获胜的最大次数
转移很明显,是在平局或者获胜的情况
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin >> n;
string s; cin >> s;
s = ' ' + s;
vector<int> dp(3);
map<char, int> p = {{'P', 0}, {'R', 1}, {'S', 2}};
for (int i = 1; i <= n; i ++ ) {
int cur = p[s[i]];
vector<int> backup = dp;
dp[(cur + 2) % 3] = max(backup[cur] + 1, backup[(cur + 1) % 3] + 1);
dp[cur] = max(backup[(cur + 1) % 3], backup[(cur + 2) % 3]);
backup = dp;
}
int maxv = *max_element(dp.begin(), dp.end());
cout << maxv << endl;
return 0;
}
E题:Xor Sigma Problem
题意
输出给定数组中所有区间的异或和,每个区间至少包含两个元素
思路
我们不可能去枚举区间的,因为有n方个
那就只能考虑每一位上对答案的贡献
而由于异或,只有个数为奇数的情况下才可以加上贡献
那我们可以先枚举每一位,然后观察数组中元素在这一位的情况
再枚举右端点,期间维护个数奇偶性的出现情况即可
代码
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n; cin >> n;
vector<int> a(n + 1);
long long ans = 0;
for (int i = 1; i <= n; i ++ ) cin >> a[i], ans -= a[i];
for (int i = 0; i < 30; i ++ ) {
int odd = 0, even = 1, cur = 0;
for (int j = 1; j <= n; j ++ ) {
if (a[j] >> i & 1) cur += 1;
if (cur & 1) {
ans += (1ll << i) * even;
odd += 1;
}else {
ans += (1ll << i) * odd;
even += 1;
}
}
}
cout << ans << endl;
return 0;
}