Problem:
最長の階段

問題

1 から n までの整数がそれぞれ 1 つずつ書かれた n 枚のカードと,1 枚の白紙の
カードがある.これら n + 1 枚のカードの内,k 枚のカードが与えられる.ただし,
1 ≤ k ≤ n である.白紙のカードには 1 から n までの整数を 1 つ書くことができ
る.与えられたカードだけで,できるだけ長い連続した整数列を作りたい.

与えられるカードが入力されたときに, 与えられたカードから作ることができる連
続した整数列の最大長を出力するプログラムを作成せよ.

例1

n = 7, k = 5 とする.6, 2, 4, 7, 1 のカードが与えられたとき,このカードを使っ
て作れる連続した整数列のうち最長のものは 1, 2 であり,その長さは 2 である.

例2

n = 7, k = 5 とする.6, 2, 4, 7 と白紙のカードが与えられたとき,このカードを
使って作れる連続した整数列のうち最長のものは,白紙のカードに 5 を書くことに
よってできる 4, 5, 6, 7 であり,その長さは 4 である.

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．入力はゼロ２つを含む行で終了する．

1 行目には,2 つの整数 n (1 ≤ n ≤ 100000) と k (1 ≤ k ≤ n) がこの順で 1 つの
空白を区切りとして書かれている.続く k 行には整数が 1 つずつ書かれており,与
えられる k 枚のカードに書かれている整数を表している.白紙のカードは 0 で表さ
れる.

採点用データのうち, 配点の 40% 分は 1 ≤ n ≤ 1000, 1 ≤ k ≤ 500 を, 配点の 20% 分は 1 ≤ n ≤ 60000, 1 ≤ k ≤ 50000 を. 配点の 40% 分は 1 ≤ n ≤ 100000, 1 ≤ k ≤ 100000 を満たす.

データセットの数は 5 を超えない．

出力

データセットごとに整数を1行に出力する．

入出力例

入力例

7 5
6
2
4
7
1
7 5
6
2
0
4
7
0 0

出力例

2
4

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in C# (judge verdict: Accepted)

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

namespace _517_LongestSteps
{
	class Program
	{
		static void Main ( string[] args )
		{
			while (true)
			{
				//input
				int[] orderNumber = Console.ReadLine ().Split (' ').Select (str => int.Parse (str)).ToArray ();

				bool isEnd = orderNumber.All (item => item == 0);
				if (isEnd)
				{
					break;
				}

				int dealCardCount = orderNumber[1];
				int[] cardArray = new int[dealCardCount];
				for (int lp = 0; lp < cardArray.Length; lp++)
				{
					cardArray[lp] = int.Parse (Console.ReadLine ());
				}

				//process
				int whiteCardCount = cardArray.Count (item => item == 0);
				cardArray = cardArray.Where (item => item != 0).OrderBy (item => item).ToArray ();

				List<ChainNumber> list = new List<ChainNumber> (cardArray.Length / 10);

				int previousItem = cardArray[0];
				int count = 1;

				//????´?????????¨??????
				for (int lp = 1; lp < cardArray.Length; lp++)
				{
					//????????????
					int item = cardArray[lp];

					//???????????¨????????????= n + 1??§????????°
					if (previousItem + 1 == item)
					{
						//????????????????¢???????
						count++;
					}
					//!= n + 1??§????????°
					else
					{
						//?????¨?????? - ???????????§?¨???????????????????????????¢???????????????????????????
						int spaceCount = item - previousItem - 1;

						//????´??????°??????
						ChainNumber number = new ChainNumber (count, spaceCount);
						list.Add (number);

						//????????????
						count = 1;
					}

					previousItem = item;

					//????????????
					if (lp + 1 == cardArray.Length)
					{
						ChainNumber number = new ChainNumber (count, 0);
						list.Add (number);
					}
				}

				int loop = 0;
				int maxLength = 0;

				//?????¨??????????´?????????¨??????????????§?????????????±???????
				while (loop < list.Count)
				{
					//?????????
					int length = 0;
					int instanceWhiteCardCount = whiteCardCount;

					//????´??????????????????????????´?????¶?????????????????????§
					while (loop < list.Count)
					{
						length += list[loop].Length;

						int needWhiteCardCount = list[loop].SpaceCount;

						//????´?????¶?????????°
						if (needWhiteCardCount <= instanceWhiteCardCount)
						{
							//?¶????
							instanceWhiteCardCount -= needWhiteCardCount;
							length += needWhiteCardCount;

							//????????????????????????
							loop++;
						}
						else
						{
							//?????????
							break;
						}
					}

					//????????????????????????
					loop++;

					//????´?????????£???????????°
					if (0 < instanceWhiteCardCount)
					{
						length += instanceWhiteCardCount;
					}

					//??????
					if (maxLength < length)
					{
						maxLength = length;
					}
				}

				//output
				Console.WriteLine (maxLength);
			}
		}

		class ChainNumber
		{
			public ChainNumber ( int length,int spaceCount )
			{
				this.Length = length;
				this.SpaceCount = spaceCount;
			}

			public int Length { private set; get; }
			public int SpaceCount { private set; get; }
		}
	}
}