🔵
【ABC363】AtCoder Beginner Contest 363【C++】
コンテスト名
AtCoder Beginner Contest 363
コンテストURL
開催日
2024/07/20 21:00-22:40
A: Piling Up
解法
- 問題文通り条件分岐する
- 計算して求める
(\lfloor \frac{R}{100} \rfloor + 1) \times 100 - R
ABC363_1A.cpp
#include <iostream>
using namespace std;
int main(){
int r;
cin >> r;
if(r<=99){
cout << 99 - r + 1 << endl;
}else if(r<=199){
cout << 199 - r + 1 << endl;
}else if(r<=299){
cout << 299 - r + 1 << endl;
}
return 0;
}
ABC363_2A.cpp
#include <iostream>
using namespace std;
int main(){
int r;
cin >> r;
cout << (r / 100 + 1) * 100 - r << endl;
return 0;
}
B: Japanese Cursed Doll
解法
- 問題文通りシミュレーションする
- 毎回条件を満たしているか判定し、全員の髪の長さを
増やす1
- 毎回条件を満たしているか判定し、全員の髪の長さを
-
番目に髪が長い人の髪の長さがP 以上になる日を求めるT - 髪の長さの降順にソートして
番目の人の髪の長さを取得するP
- 髪の長さの降順にソートして
ABC363B_1.cpp
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n, t, p;
cin >> n >> t >> p;
vector<int> L(n);
for(int i=0; i<n; i++){
cin >> L[i];
}
int ans = 0;
while(true){
int cnt = 0;
for(int i=0; i<n; i++){
if(L[i]>=t){
cnt++;
}
}
if(cnt>=p){
break;
}
ans++;
for(int i=0; i<n; i++){
L[i]++;
}
}
cout << ans << endl;
return 0;
}
ABC363B_2.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n, t, p;
cin >> n >> t >> p;
vector<int> L(n);
for(int i=0; i<n; i++){
cin >> L[i];
}
sort(L.rbegin(), L.rend());
if(L[p-1]>=t){
cout << 0 << endl;
}else{
cout << t - L[p-1] << endl;
}
return 0;
}
C: Avoid K Palindrome 2
解法
- 順列全探索
- 文字列
を昇順にソートしてからS next_permutation()
にかける - 長さ
の回文を部分文字列として含むかを全探索して判定するK
ABC363C.cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
string s;
cin >> s;
sort(s.begin(), s.end());
int cnt = 0;
do{
bool flag = true;
for(int i=0; i<=n-k; i++){
string x = s.substr(i, k);
string y = x;
reverse(y.begin(), y.end());
if(x==y){
flag = false;
break;
}
}
if(flag){
cnt++;
}
}while(next_permutation(s.begin(), s.end()));
cout << cnt << endl;
return 0;
}
D: Palindromic Number
解法
- 回文数の法則を考える
-
桁の回文数を昇順に列挙すると、上位d 桁の昇順に並んでいる\lceil \frac{d}{2} \rceil - 上位
桁について考える\lceil \frac{d}{2} \rceil -
桁の回文数はd 個ある9 \times 10^{\lfloor \frac{d - 1}{2} \rfloor} -
番目の回文数が何桁であるかを探して求めるN
-
-
桁の回文数に注意する1
ABC363D.cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(){
long long int n;
cin >> n;
if(n<=10){
cout << n - 1 << endl;
return 0;
}
long long int cnt = 10;
int keta;
long long int x = 1, y, z;
for(keta=2; ; keta++){
if(n<=cnt){
break;
}
if(keta%2==1){
x *= 10;
}
z = x;
y = x * 9;
cnt += y;
}
n -= (cnt - y);
string ans = to_string(z + n - 1);
string rans;
if(keta%2){
rans = ans;
}else{
rans = ans.substr(0, ans.size()-1);
}
reverse(rans.begin(), rans.end());
ans += rans;
cout << ans << endl;
return 0;
}
E: Sinking Land
解法
- ダイクストラ法
- 初めて海に接した年
で場合分けするx -
ならば、A_{i, j} > x 年後に沈むA_{i, j} -
ならば、A_{i, j} \leqq x 年後に沈むx
-
- 沈む年を
vector<vector<int>>
に記録する - 沈む年と座標を
priority_queue<tuple<int, int, int>>
にプッシュする - 最初から海に接している外周の区画で初期化する
-
map<int, int>
で各年に沈んだ区画数を記録する
ABC363E.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <tuple>
using namespace std;
int main(){
int h, w, y;
cin >> h >> w >> y;
vector<vector<int>> G(h, vector<int>(w));
for(int i=0; i<h; i++){
for(int j=0; j<w; j++){
cin >> G[i][j];
}
}
vector<vector<int>> sink(h, vector<int>(w, -1));
priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> Q;
for(int i=0; i<h; i++){
Q.emplace(G[i][0], i, 0);
sink[i][0] = G[i][0];
Q.emplace(G[i][w-1], i, w-1);
sink[i][w-1] = G[i][w-1];
}
for(int i=0; i<w; i++){
Q.emplace(G[0][i], 0, i);
sink[0][i] = G[0][i];
Q.emplace(G[h-1][i], h-1, i);
sink[h-1][i] = G[h-1][i];
}
vector<int> dx = {0, 1, 0, -1}, dy = {1, 0, -1, 0};
while(!Q.empty()){
auto [height, x, y] = Q.top();
Q.pop();
if(sink[x][y]!=height){
continue;
}
for(int i=0; i<4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx<0 || nx>h-1 || ny<0 || ny>w-1){
continue;
}
if(sink[nx][ny]>0){
continue;
}
int maxv = max(height, G[nx][ny]);
sink[nx][ny] = maxv;
Q.emplace(maxv, nx, ny);
}
}
map<int, int> ans;
for(int i=0; i<h; i++){
for(int j=0; j<w; j++){
ans[sink[i][j]]++;
}
}
int cnt = h * w;
for(int i=1; i<=y; i++){
cout << cnt - ans[i] << endl;
cnt -= ans[i];
}
return 0;
}
Discussion