🔵
【ABC353】AtCoder Beginner Contest 353【C++】
コンテスト名
AtCoder Beginner Contest 353
コンテストURL
開催日
2024/05/11 21:00-22:40
A: Buildings
解法
- 左から順番に判定して 1 番目のビルより高いビルがあったらプログラム終了
ABC353A.cpp
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> H(n);
for(int i=0; i<n; i++){
cin >> H[i];
}
for(int i=1; i<n; i++){
if(H[i]>H[0]){
cout << i+1 << endl;
return 0;
}
}
cout << -1 << endl;
return 0;
}
B: AtCoder Amusement Park
解法
- 問題文通りにシミュレーションする
- 空席数を記録しておいて先頭グループの人数と比較する
- 空席数が先頭グループの人数より多いなら先頭グループを乗せる
- 空席数が先頭グループの人数より少ないならアトラクションをスタートさせて空席数を
にリセットするK
ABC353B.cpp
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
vector<int> A(n);
for(int i=0; i<n; i++){
cin >> A[i];
}
int cnt = 0;
for(int i=0; i<n; ){
int vacant = k;
while(i<n && vacant>=A[i]){
vacant -= A[i];
i++;
}
cnt++;
}
cout << cnt << endl;
return 0;
}
C: Sigma Problem
解法
- 二分探索で超過分の組み合わせ数を求める
-
のときx + y < 10^8 、f(x, y) = x + y のときx + y \geqq 10^8 f(x, y) = x + y - 10^8 -
の総和を求めてx + y となる組み合わせ数分だけ総和からx + y \geqq 10^8 を引く10^8 - 各
についてx となるx + y \geqq 10^8 の数をそれぞれ求めるy - 数列
を昇順にソートしてA となるy \geqq 10^8 - x の数を二分探索で求めるy -
自身が 2 回選ばれる場合を除くことに注意するx -
となる場合x + x \geqq 10^8
-
- 数列
ABC353C.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n;
cin >> n;
const int MOD = 1e8;
long long int sum = 0;
vector<int> A(n);
for(int i=0; i<n; i++){
cin >> A[i];
sum += A[i];
}
sum *= (n-1);
sort(A.begin(), A.end());
long long int cnt = 0;
for(int i=0; i<n; i++){
int over = n - (lower_bound(A.begin(), A.end(), MOD-A[i]) - A.begin());
if(n-over<=i){
over--;
}
cnt += over;
}
cnt /= 2;
cout << sum - MOD * cnt << endl;
return 0;
}
D: Another Sigma Problem
解法
-
の各f(A_i, A_j) について考えるA_j - ある数が連結した値の右側になるときだけを考える
-
が連結した値の右側になる回数はA_j 回j - 1 -
の桁数をA_j とおくK_j -
が連結した値の右側になるときの総和はA_j A_j \times (j - 1) + \sum\limits_{i = 1}^{j - 1} A_i \times 10^{K_j} -
は右側のA_j \times (j - 1) が何回加算されるかA_j -
は右側が\sum\limits_{i = 1}^{j - 1} A_i \times 10^{K_j} のときの左側の総和A_j -
の桁数分だけ左にずれるA_j -
は累積和として先に求めて記録しておく\sum\limits_{i = 1}^{j - 1} A_i
-
-
-
の扱いに注意するmod -
modpow()
を使用
-
ABC353D.cpp
#include <iostream>
#include <vector>
using namespace std;
int ketacalc(int x){
int cnt = 1;
while(x>=10){
x /= 10;
cnt++;
}
return cnt;
}
long long int modpow(long long int a, long long int n, long long int m){
long long int res = 1;
while(n>0){
if(n&1){
res = res * a % m;
}
a = a * a % m;
n >>= 1;
}
return res;
}
int main(){
int n;
cin >> n;
const int MOD = 998244353;
vector<int> A(n);
for(int i=0; i<n; i++){
cin >> A[i];
}
vector<long long int> S(n+1);
for(int i=0; i<n; i++){
S[i+1] += (S[i] + A[i]);
}
long long int sum = 0;
for(int i=1; i<n; i++){
long long int right = (long long int)A[i] * i;
long long int left = S[i]%MOD * modpow(10, ketacalc(A[i]), MOD);
sum += (right + left) % MOD;
sum %= MOD;
}
cout << sum << endl;
return 0;
}
Discussion