【题解】AtCoder ABC365
T1
按题意模拟即可。
#include <bits/stdc++.h>
using namespace std;
int y;
int main(){
scanf("%d", &y);
if(y % 4 != 0)
printf("365\n");
else if(y % 4 == 0 && y % 100 != 0)
printf("366\n");
else if(y % 100 == 0 && y % 400 != 0)
printf("365\n");
else if(y % 400 == 0)
printf("366\n");
return 0;
}
T2
用 pair 存储数据和它的编号,从小到大排序之后输出倒数第二个数据的编号。
(pair 的默认排序方法是按照 first 从小到大排序)
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int n;
pair<int, int> arr[N];
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &arr[i].first), arr[i].second = i;
sort(arr + 1, arr + 1 + n);
printf("%d\n", arr[n - 1].second);
return 0;
}
T3
如果 \(x\) 的值很大,最后的总花费应为 \(\sum a\),所以如果有 \(\sum a \leq m\),输出 infinite,结束程序。
对于剩下的情况,可以发现,对于 \(x' < x\),若 \(x\) 的补贴限额能使总花费不超过 \(m\),\(x'\) 也能做到;对于 \(x' > x\),若 \(x\) 会让总花费超过 \(m\),\(x'\) 也会。所以,本题的答案具有单调性:在一定范围内,\(x\) 越大,总花费越大,反之则越小。
考虑用二分答案求解。令左端点 \(l = 0\),右端点 \(r = 2\times 10^{14} + 1\)(数据最大范围),对于一个 \(x\),验证它是否能让总花费不超过 \(m\)。若可以,将左端点移到 \(x\),若不可以,将右端点移到 \(x\)。最终 \(l + 1 = r\) 时,\(l\) 的值即为 \(x\) 的最大值。
注意:数据较大,要开 long long。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 5;
const ll inf = 2e14 + 1;
ll n, m, arr[N];
inline bool check(ll x){
ll sum = 0;
for(int i = 1; i <= n; i++)
sum += min(x, arr[i]);
return sum <= m;
}
int main(){
scanf("%lld%lld", &n, &m);
ll s = 0;
for(int i = 1; i <= n; i++){
scanf("%lld", &arr[i]);
s += arr[i];
}
if(s <= m){
printf("infinite\n");
return 0;
}
ll l = 0, r = inf;
while(l + 1 != r){
ll mid = l + r >> 1;
if(check(mid))
l = mid;
else
r = mid;
}
printf("%lld\n", l);
return 0;
}
T4
设 \(f_{i, 0}\) 表示前 \(i\) 局高桥在不违反规则的情况下平局时,最多能胜多少场;
设 \(f_{i, 1}\) 表示前 \(i\) 局高桥在不违反规则的情况下获胜时,最多能胜多少场。
设 \(g(c) = \begin{cases}\text{'P'} & c = \text{'R'} \\ \text{'S'} & c = \text{'P'} \\ \text{'R'} & c = \text{'S'}\end{cases}\)(即对方出 \(c\) 时高桥的对策)
有:
注意初始化:\(f_{1, 0} = 0, f_{1, 1} = 1\)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, dp[N][2];
char s[N];
inline char get(char c){
if(c == 'R')
return 'P';
else if(c == 'P')
return 'S';
else if(c == 'S')
return 'R';
}
int main(){
scanf("%d%s", &n, s + 1);
dp[1][1] = 1, dp[1][0] = 0;
for(int i = 2; i <= n; i++){
char c1 = s[i - 1], c2 = get(s[i - 1]), c3 = s[i], c4 = get(s[i]);
dp[i][0] = max((c1 != c3 ? dp[i - 1][0] : -1), (c2 != c3 ? dp[i - 1][1] : -1));
// 由于 dp 数组中不会出现负数,所以取最大值时如果一个条件不成立,就会自动转成另一个值直接被赋值给 dp
dp[i][1] = max((c1 != c4 ? dp[i - 1][0] : -1), (c2 != c4 ? dp[i - 1][1] : -1)) + 1;
}
printf("%d\n", max(dp[n][0], dp[n][1]));
return 0;
}

浙公网安备 33010602011771号