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++11 (judge verdict: Accepted)

#include<array>
#include<iostream>
#include<algorithm>

using namespace std;
array<int, 1000000> buf;

typedef array<int, 1000000>::iterator it_type;
int get_longest_steps_0(it_type first, it_type last) {
	it_type it = ++first;
	it_type it_temp = first;
	int result = 0;
	while (it != last) {
		auto it_duration = it - first;
		auto sub = *it - *first;
		if (it_temp	> first) {
			// 整数列の間に白紙があるケース
			if (it_duration + 1 != sub) {
				result = max(result, static_cast<int>(it_duration + 1));
				if (it_duration + 2 == sub) {
					// 次の整数列と白紙で連結できるケース
					first = it_temp;
					it_temp = it;
				}
				else {
					// 白紙で連結できない
					first = it;
				}
			}
		}
		else {
			if (it_duration != sub){
				if (it_duration + 1 == sub) {
					// 白紙で連結可能なので戻り値にしない。
					it_temp = it;
				}
				else {
					// 連結不可能なの白紙の分を+1する
					result = max(result, static_cast<int>(it_duration + 1));
					first = it;
				}
			}
		}
		++it;
	}
	result = max(result, static_cast<int>(it - first + 1));
	return result;
}

int get_longest_steps_non_0(it_type first, it_type last) {
	it_type it = first;
	int result = 0;
	while (it != last) {
		if (it - first != *it - *first) {
			result = max(result, static_cast<int>(it - first));
			first = it;
		}
		++it;
	}
	return result;
}

//template<typename T>
int get_longest_steps(it_type first, it_type last) {
	int result;
	if (*first == 0) {
		result = get_longest_steps_0(first, last);
	}
	else {
		result = get_longest_steps_non_0(first, last);
	}
	return result;
}


int main() {

	while (true) {
		int n, k;
		cin >> n >> k;

		if (n == 0 && k == 0) {
			break;
		}

		for (int i = 0; i < k; i++) {
			cin >> buf[i];
		}
		
		it_type end = buf.begin() + k;

		sort(buf.begin(), end);

		cout << get_longest_steps(buf.begin(), end) << endl;

	}

	return 0;
}