Motsu_xe 競プロのhogeやfuga

Motsu_xeが競技プログラミングに関する何かを適当に書き連ねるブログになるはずです。

ABC145 A - Circle

昨日はABC145お疲れ様でした。私は5完で終わってしまい、黄色返上しろって感情になりましたが、皆さんはいかがでしたでしょうか?

 
今回はそんなABC145の中で私が一番最後に通した、A - Circleの解説記事を書いていきたいと思います。

A - Circle

問題概要

整数rが与えられる。半径rの円の面積が半径1の円の面積の何倍であるか求めよ。答えは制約の下では必ず整数になるので、整数として出力せよ。

制約

1\leq r\leq100

考察

 半径rの円の面積は\pi r^2であり、半径1の円の面積は\piとなります。ここで次のようなコードを考えます。

#include <iostream>
#include <cmath>

int main(){
    int r;
    std::cin >> r;
    const double pi = acos(-1.0);
    double circle_r = pi * r * r;
    std::cout << circle_r / pi << std::endl;
}

投げてみます。

atcoder.jp


通っちゃったよ。以上です。

事の顛末

今更ABC-Aの解説記事など需要がありませんね?わかります。
なんでこんな記事を書いているかというお話をしたいと思います。
ふと競プロブログなら、解説記事くらい書きたくなることがあるだろうと思ったのですが、どうやって解説記事って書くんですかね?となりました。じゃあ簡単な問題でとりあえず形式だけ確かめてみようと思って書いてみました。
以上です。

閑話休題

わざわざ出力を整数にしろといっているのに、double型で出力して通ってしまいました。なぜでしょうか?
浮動小数点数a2^c(1\leq a \lt 2,\ c:整数)という形で保持されています。
C++でdouble型をcoutで出力する際、デフォルトでは10進数6桁分の精度で出力されます。つまり1.23456789は1.23457と出力され、123.456789は123.457と出力されます。ただし事はそう単純じゃなく、以下のようになっています。

入力 出力
1.23456789 1.23457
123.456789 123.457
0.00123456789 0.00123457
123456789 123457e+08
0.00000123456789 1.23457e-06
1234 1234
100 100

e±nというのは10^{\pm n}という意味です。
このように基本的には6桁の精度で出力されるのですが、かなり複雑な表示のされかたをしていることがわかります。
C言語のprintfに出力で、フォーマット指定子としてgを選んだときの挙動となっているので、詳しくはそれを調べてみてください。
今回の出力としてありえる範囲は1以上100^2以下の整数です。coutは10^6未満の整数は整数であるかのように表示されるので、今回は整数と同じフォーマットで出力されたためにACできたというわけです。

まともな解法

今回はこの解法でACできましたが、答えが整数になるなら、整数型で答えを保持するべきですし、今回のように小数で扱う必要がない問題では、整数の範囲で計算すべきです。浮動小数点数の保持の仕方を少し勉強すればわかることですが、小数は常に誤差の危険性と隣り合わせで必要のないときは基本的に使用を控えるべきです。
相似比rの図形の面積比はr^2ですし、\frac{\pi r^2}{\pi}=r^2ですので、r^2を計算すれば終わる問題ですね。次のように実装をすれば良いです。

#include <iostream>

int main(){
    int r;
    std::cin >> r;
    std::cout << r * r << std::endl;
}

Submission #8505321 - AtCoder Beginner Contest 145

これで終わりです。

感想

まあこの問題で詰まる人はなかなかいなかったと思いますけど、こう記事にしてみようと思ったら書く事はあるものですね。浮動小数点数の出力フォーマットについてしっかり書こうかとも思いましたが、普通にめんどすぎるので適当になってしまい、結局情報量0になってしまった事は謝罪します。
記事中にソースコード埋め込む方法、リンクを埋め込む方法など様々な勉強ができたので、今後解説記事書きたくなったら書きたいと思います。それではまた会いましょう。


スポンサードリンク