トップページに戻る    次の競技プログラミングの問題へ    前の競技プログラミングの問題へ

ABC-064-C Colorful Leaderboard

■■■問題■■■

AtCoderでは、コンテストに参加すると「色」が付き、
これはレートによって次のように変化します:

●レート    1- 399:灰色
●レート  400- 799:茶色
●レート  800-1199:緑色
●レート 1200-1599:水色
●レート 1600-1999:青色
●レート 2000-2399:黄色
●レート 2400-2799:橙色
●レート 2800-3199:赤色

また、レートが3200以上になると色を自由に変えることができます。
現在N人の人がAtCoderのコンテストに参加したことがあり、i人目の人のレートはaiです。
そのとき、色の種類数の最小値と最大値を求めなさい。

■■■入力■■■

N
a1 a2 ・・・ aN

●1 <= N <= 100
●1 <= ai <= 4800
●aiは整数である

■■■出力■■■

色の種類数の最小値、最大値をこの順で空白区切りで出力しなさい。


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "Input1";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("4");
            WillReturn.Add("2100 2500 2700 2700");
            //2 2
            //レート2100の人は「黄色」であり、
            //それ以外の人は「橙色」なので、色の種類数は2となる。
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("5");
            WillReturn.Add("1100 1900 2800 3200 3200");
            //3 5
            //レート1100の人は「緑色」、
            //レート1900の人は「青色」、
            //レート2800の人は「赤色」である。
            //
            //4人目が「赤色」を選び、5人目が「青色」を選んだ時、色の種類数は3であり、
            //これは最小値を取る一つの例である。
            //
            //4人目が「紫色」を選び、5人目が「黒色」を選んだ時、色の種類数は5であり、
            //これは最大値を取る一つの例である。
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("20");
            WillReturn.Add("800 810 820 830 840 850 860 870 880 890 900 910 920 930 940 950 960 970 980 990");
            //1 1
            //この場合全員が「緑色」である。よって色の種類数は1となる。
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();
        int[] AArr = InputList[1].Split(' ').Select(X => int.Parse(X)).ToArray();

        var CntDict = new Dictionary<int, int>();
        foreach (int EachA in AArr) {
            int TruncRate = DeriveTruncRate(EachA);
            if (CntDict.ContainsKey(TruncRate)) {
                CntDict[TruncRate]++;
            }
            else CntDict[TruncRate] = 1;
        }

        int Cnt1 = CntDict.Where(X => X.Key <= 2800).Count();

        int Cnt2;
        var Query = CntDict.Where(X => X.Key == 3200);
        if (Query.Any()) Cnt2 = Query.Sum(X => X.Value);
        else Cnt2 = 0;

        //色の種類数の最小値
        int MinCnt;
        if (Cnt1 > 0) MinCnt = Cnt1;
        else MinCnt = 1;

        //色の種類数の最大値
        int MaxCnt = Cnt1 + Cnt2;

        Console.WriteLine("{0} {1}", MinCnt, MaxCnt);
    }

    //切り捨てたレートを返す
    static int DeriveTruncRate(int pRate)
    {
        if (pRate <= 399) return 1;
        if (pRate <= 799) return 400;
        if (pRate <= 1199) return 800;
        if (pRate <= 1599) return 1200;
        if (pRate <= 1999) return 1600;
        if (pRate <= 2399) return 2000;
        if (pRate <= 2799) return 2400;
        if (pRate <= 3199) return 2800;
        return 3200;
    }
}


解説

3200未満と3200以上を集計してから、
色の種類数の最小値と最大値を求めてます。