概要
問題の解き方をまとめました。
- 2025.10.5 A-D
A Diagonal String #ABC090-A
問題
$3 \times 3$ の正方形のマスがあり、各マスには英小文字が書かれている。マス目の左上と右下を直線で結んだ時にできる文字列を出力する。
- 入力は英小文字からなる
解法
- 左上から順に読む。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)n; i++)
vector<string> S(3);
int main() {
rep(i, 3) cin >> S.at(i);
rep(i, 3) cout << S.at(i).at(i); //左上から順に読む
cout << endl;
return 0;
}
B Palindromic Numbers #ABC090-B
問題
$A$ 以上 $B$ 以下の整数のうち、回文数となるものの個数を求める。
- $10000 \leq A \leq B \leq 99999$
解法
全探索
- $A$ 以上 $B$ 以下の整数を文字列に直して、回文数であるかを求める。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
#define repu(i, s, t) for (int i = (int)s; i < (int)t; i++)
int A, B;
int main() {
cin >> A >> B;
int ans = 0;
repu(i, A, B+1) { //A 以上 B 以下の整数を全探索
string s = to_string(i); //整数を文字列にする
if (s.at(0) == s.at(4) && s.at(1) == s.at(3)) ans++; //0 番目の数字と 4 番目の数字、1 番目の数字と 3 番目の数字が同じだったら回文数
}
cout << ans << endl;
return 0;
}
C Flip, Flip, and Flip...... #ABC090-C
問題
$N \times M$ のマス目に表裏のあるカードが置かれていて、最初は全て表を向いている。全てのカードについて、辺や頂点で接するカードと自分自身をひっくり返す操作を、一回ずつ行う。全ての操作を終えた時に裏を向いているカードの数を求める。
- $1 \leq N, M \leq 10^9$
- 入力は全て整数
解法
- カードが奇数回ひっくり返された時にカードは裏面を向く。
- カードが一枚しか置いていないとき、1 回だけひっくり返す。
- カードが縦か横に一列で並んでいるとき、端は 2 回、それ以外は 3 回ひっくり返す。
- 上記以外の場合、角を 4 回、一番外側を 6 回、それ以外を 9 回ひっくり返す。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
int64_t N, M;
int main() {
cin >> N >> M;
int64_t ans = 0; //裏を向いているカードの数
if (N == 1 && M == 1) ans = 1; //カードが一枚だけの時
else if (N == 1 || M == 1) ans = max(N, M) - 2; //カードが一列に並んでいる時
else ans = (N - 2) * (M - 2); //その他の場合
cout << ans << endl;
return 0;
}
D Remainder Reminder #ABC090-D
問題
$N$ 以下の整数の 2 つの組 $(a, b)$ がある。$a$ を $b$ で割った余りが $K$ 以上の時、$a$ と $b$ の組としてありうるものの個数を求める。
- $1 \leq N \leq 10^5$
- $0 \leq K \leq N - 1$
- 入力は全て整数
解法
- $K$ が $0$ の時、$N$ 以下の全ての整数の組み合わせがありうる。
- $b$ が決まっている時の、$a$ がとりうる値の個数を求める。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
#define repu(i, s, t) for (int i = (int)s; i < (int)t; i++)
int64_t N, K;
int main() {
cin >> N >> K;
if (K == 0) { cout << N * N << endl; return 0; } //K が 0 の時
int64_t ans = 0;
repu(b, K+1, N+1) ans += (b-K)*(N/b) + max((int64_t)0, (N%b)-(K-1));
//a = b * i + k で表すことができる、k は K 以上
//i < N / b の時は、b - K 個の a がありうる
//i = N / b の時は、N を超えてはいけないので N を b で割った余りから K - 1 を引く
cout << ans << endl;
return 0;
}