Problem:
Score : 300 points

Problem Statement

You are given an integer sequence of length N, a_1,a_2,...,a_N.

For each 1≤i≤N, you have three choices: add 1 to a_i, subtract 1 from a_i or do nothing.

After these operations, you select an integer X and count the number of i such that a_i=X.

Maximize this count by making optimal choices.

Constraints

1≤N≤10^5

0≤a_i<10^5 (1≤i≤N)

a_i is an integer.

Input

The input is given from Standard Input in the following format:

N
a_1 a_2 .. a_N

Output

Print the maximum possible number of i such that a_i=X.

Sample Input 1

7
3 1 4 1 5 9 2

Sample Output 1

4

For example, turn the sequence into 2,2,3,2,6,9,2 and select X=2 to obtain 4, the maximum possible count.

Sample Input 2

10
0 1 2 3 4 5 6 7 8 9

Sample Output 2

3

Sample Input 3

1
99999

Sample Output 3

1

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

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

public class VC0407M_04
{

    public static void Main()
    {
        int c = InLine<int>();
        int[] ints = InLineArg<int>();
        var dic = new Dictionary<int, int>();
        for(int i = 0;i < c; i++)
        {
            for(int k = 0;k < 3; k++)
            {
                int n = ints[i] - 1 + k;
                if (dic.ContainsKey(n)) dic[n]++;
                else dic.Add(n, 1);
            }
        }
        int max = 0;
        foreach(var i in dic.Values)
        {
            if (i > max) max = i;
        }
        Out(max);
    }

    /* Template */
    private static object[] nullobj = null;

    //文字コード変換
    public static int ConvertInt(char c)
    {
        return c;
    }

    //入力:1入力配列
    public static A[] InArgs<A>(int count)
    {
        A[] var = default(A[]);
        InArgs(count, ref var, ref nullobj, ref nullobj);
        return var;
    }

    //入力:1入力配列
    public static void InArgs<A>(int count, ref A[] var)
    {
        InArgs(count, ref var, ref nullobj, ref nullobj);
    }

    //入力:2入力配列
    public static void InArgs<A, B>(int count, ref A[] var1, ref B[] var2)
    {
        InArgs(count, ref var1, ref var2, ref nullobj);
    }

    //入力:3入力配列
    public static void InArgs<A, B, C>(int count, ref A[] var1, ref B[] var2, ref C[] var3)
    {
        A a = default(A);
        B b = default(B);
        C c = default(C);
        for (int i = 0; i < count; i++)
        {
            InLine(ref a, ref b, ref c);
            var1[i] = a;
            if (var2 != null) var2[i] = b;
            if (var3 != null) var3[i] = c;
        }
    }

    //入力:1入力
    public static A InLine<A>()
    {
        A var = default(A);
        InLine(ref var);
        return var;
    }

    //入力:1入力
    public static void InLine<A>(ref A var)
    {
        InLine(ref var, ref nullobj, ref nullobj);
    }

    //入力:2入力
    public static void InLine<A, B>(ref A var1, ref B var2)
    {
        InLine(ref var1, ref var2, ref nullobj);
    }

    //入力:3入力
    public static void InLine<A, B, C>(ref A var1, ref B var2, ref C var3)
    {
        object[] o = new object[] { var1, var2, var3 };
        Type[] t = new Type[] { typeof(A), typeof(B), typeof(C) };
        if (var3 == null)
        {
            if (var2 == null) o = new object[] { var1 };
            else o = new object[] { var1, var2 };
        }

        var line = Console.ReadLine();
        string[] s;
        if (o.Length == 1) s = new string[1] { line };
        else s = line.Split(' ');
        for (int i = 0; i < s.Length; i++)
        {
            if (typeof(int) == t[i]) o[i] = int.Parse(s[i]);
            else if (typeof(long) == t[i]) o[i] = long.Parse(s[i]);
            else if (typeof(double) == t[i]) o[i] = double.Parse(s[i]);
            else o[i] = s[i];
        }
        var1 = (A)o[0];
        if (var2 != null) var2 = (B)o[1];
        if (var3 != null) var3 = (C)o[2];
    }

    //入力:1行配列
    public static A[] InLineArg<A>()
    {
        A[] var = default(A[]);
        InLineArg(ref var);
        return var;
    }

    //入力:1行配列
    public static void InLineArg<A>(ref A[] arg)
    {
        object obj = null;
        Type t = typeof(A);
        string[] line = Console.ReadLine().Split(' ');
        if (typeof(int) == t) obj = line.Select(int.Parse).ToArray();
        else if (typeof(long) == t) obj = line.Select(long.Parse).ToArray();
        else if (typeof(double) == t) obj = line.Select(double.Parse).ToArray();
        else obj = line;
        arg = (A[])obj;
    }

    //文字列結合
    public static string JoinString(object[] obj, string sep)
    {
        return string.Join(sep, obj.Select(i => i.ToString()).ToArray());
    }

    //出力
    public static void Out(object o)
    {
        Console.WriteLine(o);
    }

    //出力:Yes
    public static void OutYes()
    {
        Console.WriteLine("Yes");
    }

    //出力:No
    public static void OutNo()
    {
        Console.WriteLine("No");
    }

    //出力:YES
    public static void OutYES()
    {
        Console.WriteLine("YES");
    }

    //出力:NO
    public static void OutNO()
    {
        Console.WriteLine("NO");
    }

    //辞書生成
    private static Dictionary<A, B> PutDict<A, B>(A[] key, B[] value)
    {
        if (key.Length != value.Length) return null;
        var dic = new Dictionary<A, B>();
        for (int i = 0; i < key.Length; i++)
        {
            if (!dic.ContainsKey(key[i])) dic.Add(key[i], value[i]);
            else dic[key[i]] = value[i];
        }
        return dic;
    }

    //公約数
    public static int[] CommonDivisor(int num)
    {
        return CommonDivisor((long)num).Select(i => (int)i).ToArray();
    }

    public static long[] CommonDivisor(long num)
    {
        long l = 2, n = num;
        long[] result = new long[0];

        while (l * l <= num)
        {
            if (n % l == 0)
            {
                n /= l;
                Array.Resize(ref result, result.Length + 1);
                result[result.Length - 1] = l;
            }
            else l++;
        }
        if (n != 1)
        {
            Array.Resize(ref result, result.Length + 1);
            result[result.Length - 1] = n;
        }
        return result;
    }

    //大小比較
    public static bool Compare(bool equal, long a, long x)
    {
        return Compare(equal, a, x, long.MaxValue, true);
    }

    public static bool Compare(long x, long b, bool equal)
    {
        return Compare(true, long.MinValue, x, b, equal);
    }

    public static bool Compare(bool lequal, long a, long x, long b, bool requal)
    {
        if (a <= x && x <= b)
        {
            if (!lequal && x == a) return false;
            else if (!requal && x == b) return false;
            else return true;
        }
        return false;
    }

    //割り切る
    public static bool IsDivisible(long a, long b)
    {
        return a % b == 0;
    }

    //互いに素
    public static bool IsRelativelyPrime(long a, long b)
    {
        bool result = false;
        if (a > 1 && b > 1)
            result = CommonDivisor(a).Intersect(CommonDivisor(b)).ToArray().Length == 0;
        return result;
    }

    //素数判定
    public static bool IsPrimeNumber(int num)
    {
        if (num < 2) return false;
        else if (num == 2) return true;
        else if (num % 2 == 0) return false;

        double sqrtNum = Math.Sqrt(num);
        for (int i = 3; i <= sqrtNum; i += 2)
        {
            if (num % i == 0) return false;
        }
        return true;
    }

    //最大公約数
    public static int GCD(int a, int b)
    {
        return (int)GCD((long)a, b);
    }

    public static long GCD(long a, long b)
    {
        long[] acd = CommonDivisor(a).ToArray(), bcd = CommonDivisor(b).ToArray();
        Dictionary<long, int> dic1 = new Dictionary<long, int>(), dic2 = new Dictionary<long, int>();
        int count = 0;
        long n = 0, result = 1;
        for (int i = 0; i < acd.Length; i++)
        {
            if (n == acd[i]) count++;
            else
            {
                if (n != 0) dic1.Add(n, count);
                n = acd[i];
                count = 1;
            }
        }
        dic1.Add(n, count);
        n = 0;
        count = 0;
        for (int i = 0; i < bcd.Length; i++)
        {
            if (n == bcd[i]) count++;
            else
            {
                if (dic1.ContainsKey(n)) dic2[n] = Math.Max(count, dic1[n]);
                n = bcd[i];
                count = 1;
            }
        }
        if (dic1.ContainsKey(n)) dic2[n] = Math.Max(count, dic1[n]);
        foreach (long l in dic2.Keys)
        {
            result *= (long)Math.Pow(l, dic2[l]);
            Console.WriteLine($"{l}, {dic2[l]}");
        }
        return result;
    }

    //最小公倍数
    public static long LCM(long a, long b)
    {
        long[] acd = CommonDivisor(a).ToArray(), bcd = CommonDivisor(b).ToArray();
        var dic = new Dictionary<long, int>();
        int count = 0;
        long n = 0, result = 1;
        for (int i = 0; i < acd.Length; i++)
        {
            if (n == acd[i]) count++;
            else
            {
                if (n != 0) dic.Add(n, count);
                n = acd[i];
                count = 1;
            }
        }
        dic.Add(n, count);
        n = 0;
        count = 0;
        for (int i = 0; i < bcd.Length; i++)
        {
            if (n == bcd[i]) count++;
            else
            {
                if (dic.ContainsKey(n)) dic[n] = Math.Max(count, dic[n]);
                else if (n != 0) dic.Add(n, count);
                n = bcd[i];
                count = 1;
            }
        }
        if (dic.ContainsKey(n)) dic[n] = Math.Max(count, dic[n]);
        else dic.Add(n, count);
        foreach (long l in dic.Keys)
            result *= (long)Math.Pow(l, dic[l]);
        return result;
    }

    //組合せ数(nCr)
    public static double Combination(int n, int r)
    {
        if (n / 2 < r) r = n - r;
        return TotalPower(n, r + 1) / TotalPower(n - r);
    }

    //組合せ数総和(Σ(k=1,n,nCk))
    public static double CombinationSum(int n)
    {
        return Math.Pow(2, n);
    }

    //重複組合せ数(nHr)
    public static double RepetitionCombination(int n, int r)
    {
        return Combination(n + r - 1, r);
    }

    //重複組合せ数総和(Σ(k=1,n,nHk))
    public static double RepetitionCombinationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += RepetitionCombination(n, i);
        }
        return result;
    }

    //順列数(nPr)
    public static double Permutation(int n, int r)
    {
        return TotalPower(n, r + 1);
    }

    //順列数総和(Σ(k=1,n,nPk))
    public static double PermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += Permutation(n, i);
        }
        return result;
    }

    //円順列数
    public static double CircularPermutation(int n)
    {
        return TotalPower(n - 1);
    }

    //円順列数総和
    public static double CircularPermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += CircularPermutation(i);
        }
        return result;
    }



    //数珠順列数
    public static double NecklacePermutation(int n)
    {
        return CircularPermutation(n - 1) / 2;
    }

    //数珠順列数総和
    public static double NecklacePermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += NecklacePermutation(i);
        }
        return result;
    }

    //重複順列数(nΠr)
    public static double RepetitionPermutation(int n, int r)
    {
        return Math.Pow(n, r);
    }

    //重複順列数総和(Σ(k=1,n,nΠk))
    public static double RepetitionPermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += RepetitionPermutation(n, i);
        }
        return result;
    }

    //総乗
    public static double TotalPower(int max)
    {
        return TotalPower(max, 1);
    }

    public static double TotalPower(int max, int min)
    {
        double result = 1;
        for (int i = min; i <= max; i++) result *= i;
        return result;
    }

    public static double TotalPower(int[] ints)
    {
        double result = 1;
        foreach (int i in ints) result *= i;
        return result;
    }

    //総和
    public static double TotalSum(int max)
    {
        return TotalSum(max, 1);
    }

    public static double TotalSum(int max, int min)
    {
        double result = 1;
        for (int i = min; i <= max; i++) result += i;
        return result;
    }

    public static double TotalSum(int[] ints)
    {
        double result = 1;
        foreach (int i in ints) result += i;
        return result;
    }
}