C♯の勉強

C♯4.0 で TopCoder の過去問を解きます。

Codeforces Round #204: Jeff and Rounding

小数点の取り扱い

まずハマった点としては、CodeForcesのサーバー上では CultureInfo がロシアになっているため、小数点の表記が "." ではなく "," で使用される。そのため double.Parse"0.11" を渡すと Runtime Error となり "0,11" のような小数文字列を渡さないとパースできない。

入力だけではなく、出力も同様にそのまま出力すると "0,11" のようにカンマが使用されてしまう。対応方法としては、Parse系メソッドやString.Formatに英語圏のカルチャを渡すことでなんとかなる。

本題

namespace Codeforces {
    public class _352C {
        static public void Solve(TextReader cin, TextWriter cout) {
            CultureInfo ci = new CultureInfo("en-US");
            int n = int.Parse(cin.ReadLine());
            var a = cin.ReadLine().Split().Select(v => double.Parse(v, ci)).ToArray();
            var b = a.Select(v => (int)(v * 1000 + 1e-8) % 1000).ToArray();
            int nonZeroNum = b.Where(v => v != 0).Count();
            int ZeroNum = 2 * n - nonZeroNum;
            int sum = b.Sum();
            int ans = int.MaxValue;
            for (int i = Math.Max(0, n - ZeroNum); i <= Math.Min(n, nonZeroNum); i++) {
                int value = i * 1000;
                ans = Math.Min(ans, Math.Abs(value - sum));
            }
            cout.WriteLine(String.Format(ci, "{0:0.000}", ans / 1000.0));
        }

        public static void Main(string[] args) {
            Solve(Console.In, Console.Out);
        }
    }
}