AtCoder Beginners Contest 112の参加記録。
A
入力N
が1なら指定の文字列を出力, 2なら更に標準入力から数字を読み、計算結果を出力.
インタラクティブに標準入力の分岐処理を行う問題はABCだと初めて?
解答
fn main() {
let n = read_one::<String>();
if n == "1" {
println!("Hello World");
} else {
let a = read_one::<usize>();
let b = read_one::<usize>();
println!("{}", a + b);
}
}
B
(c_i, t_i)
のうち、t_i <= T
を満たす最小のc_i
を求める.
存在しない場合にはTLE
を出力する。
解答
fn main() {
let (n, t) = {
let i = read::<usize>();
(i[0], i[1])
};
let mut ct = Vec::new();
for _ in 0..n {
let i = read::<usize>();
ct.push((i[0], i[1]));
}
let ans = ct.iter()
.filter(|x| x.1 <= t)
.map(|x| x.0)
.min();
match ans {
Some(x) => println!("{}", x),
None => println!("TLE"),
}
}
C
座標(x_i, y_i)
と高度h_i
及び高度の計算式が与えられ、それを満たす中心座標及びそれの高度を求める.
制約がx < 10^2, y < 10^2, N < 10 ^ 2
なので全探索でも10^8
なので通る.
x, y
及びn
を固定すればh = max(H - (X - c_x).abs() - (Y - c_y).abs(), 0)
からH
は定まるが、最初h_i
が0
になりうるケースを考慮せずにやってWA.
そこで, クエリをh_i
によってソートすればmax(..., 0)
の結果が正になるから, ここでの条件分岐を考えずに済む.
後は各クエリがこのx, y, h
と一致するか確認する.
fn main() {
let n = read_one::<usize>();
let mut vec = Vec::new();
for _ in 0..n {
let i = read::<isize>();
vec.push((i[0], i[1], i[2]));
}
vec.sort_by_key(|x| x.2);
vec.reverse();
let mut ans_x = 0;
let mut ans_y = 0;
let mut ans_h = 0;
for x in 0..101 { for y in 0..101 {
let mut flg = true;
let h = vec[0].2 + (x - vec[0].0).abs() + (y - vec[0].1).abs();
for v in vec.iter() {
if v.2 != cmp::max(h - (x - v.0).abs() - (y - v.1).abs(), 0) {
flg = false;
continue;
}
}
if flg {
ans_x = x;
ans_y = y;
ans_h = h;
}
}}
println!("{} {} {}", ans_x, ans_y, ans_h);
}
D
数列an
の要素数N
と和M
が与えられるので、an
の各要素の最大公約数の取りうる最大値を求める.
a_1 + a_2 + ... + a_N
の最大公約数がK
であるとき, 次のように括り出すことができる.
K * (a_1' + a_2' + ... + a_N') = K * sum(a')
したがってK
はM
の約数.
次にan
の要素数をN
にするためには, a'
の要素数がN
個である必要がある.
min(sum(a'))
は全ての要素が1
の場合にN
となるので, K
は大きくてもM / N
の範囲であることがわかる.
よって, i in 1 ~ M / N
について,Mが割り切れるi
のうち最大のものが答え.
また制約からn = 1, m = 10^9
のケースがありうる. その場合処理が全て走ってしまうのでTLE(1WA), その場合の処理はアドホックに書いてしまった.
解答
fn main() {
let (n, m) = {
let i = read::<u64>();
(i[0], i[1])
};
let mut ans = 1;
if n == 1 {
println!("{}", m);
return;
}
for i in 1..(m / n + 1) {
if m % i == 0 { ans = i; }
}
println!("{}", ans);
}
所感
A -> B -> D -> Cの順で解いた.
立ち回りは悪くなかったと思う(DよりCにかけた時間の方が長かったので).
ただこのレベルで立ち回りとか考えずに全部解けるようにすべき,というのはそれはそうなので精進する.
Cに戻ってきたときに全探索が可能なことに気づくまでは早かったがそこからの比較ミスは2WAに抑えられるものだったので反省.
CよりDの方が簡単じゃないですか?
2WA以上出した時は全部消して0から書き直すと吉っぽい.
これを書いた後に見た解説放送中のコメントに, Cはmax(h) <= H <= max(h) + 200
に収まるからHについても全探索が可能、とあってなるほどなあとなった.
Comments