Problem:
連鎖

問題

次のようなゲームがある．

あるキャラクターが縦 1 列に N 個並んでいる．これらのキャラクターの色は赤，青，黄のいずれかであり，初期状態で同じ色のキャラクターが4つ以上連続して並んでいることはない．プレーヤーは，ある位置のキャラクターを選び他の色に変更することができる．この操作により同じ色のキャラクターが4つ以上連続して並ぶとそれらのキャラクターは消滅する．キャラクターが消滅することにより新たに同じ色のキャラクターが4つ以上連続して並ぶとそれらのキャラクターも消滅し，同じ色のキャラクターが4つ以上連続して並んでいる箇所がなくなるまでこの連鎖は続く．このゲームの目的は，消滅しないで残っているキャラクター数をなるべく少なくすることである．

例えば，下図の左端の状態で，上から6番目のキャラクターの色を黄色から青に変更すると，青のキャラクターが5つ連続するので消滅し，最終的に3つのキャラクターが消滅せずに残る．

初期状態における N 個のキャラクターの色の並びが与えられたとき， 1箇所だけキャラクターの色を変更した場合の，消滅しないで残っているキャラクター数の最小値 M を求めるプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

1行目はキャラクター数 N (1 ≤ N ≤ 10000) だけからなる．続く N 行には 1, 2, 3 のいずれか1つの整数が書かれており， i + 1 行目 (1 ≤ i ≤ N) は初期状態における上から i 番目のキャラクターの色を表す（1 は赤を，2 は青を，3は黄を表す）．

N が 0 のとき入力の終了を示す．データセットの数は 5 を超えない．

出力

データセットごとに, 消滅しないで残っているキャラクター数の最小値 M を１行に出力せよ．

入出力例

入力例

12
3
2
1
1
2
3
2
2
2
1
1
3
12
3
2
1
1
2
3
2
1
3
2
1
3
0

出力例

3
12

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

Solution in C (judge verdict: Time Limit Exceeded)

#include <stdio.h>
int main(){
	int N;
	int rensa;
	int count;
	int i,j,k;//ループに用いるカウント
	int a,b,end,start;
	int color;
	scanf("%d",&N);
	while(N!=0){
		int data[N];
		rensa=10000;//最小値を更新していく
		for(i=0;i<N;i++){
			scanf("%d",&data[i]);
		}
		for(i=0;i<N;i++){//開始地点
			for(j=1;j<4;j++){//変更色
				printf("%dを%dに\n",i,j);
				count=1;
				color=j;
				a=0;
				b=0;
				//色をjに変更（基準）
				k=i-1;//基準より前で同じ色のものを探す。
				while(k>=0&&data[k]==color){
					a++;
					printf("%dは同色\n",k);
					k--;
				}
				k=i+1;//基準より後ろで同じ色のものを探す。
				while(k<N&&data[k]==color){
					b++;
					printf("%dは同色\n",k);
					k++;
				}
				while(1){
					if(a+b>=4&&data[i-a-1]==data[i+b+1]){//実際に消せたなら続行
						count+=a+b;
						printf("%d個消えました。通算%d個\n",a+b,count);
						start=i-a;
						end=i+b;
						a=0;
						b=0;
						if(end+1==N||start==0){
							printf("gotoが機能\n");
							goto END;
						}
						k=start-1;
						color=data[k];
						printf("色は%d\n",color);
						while(k>=0&&data[k]==color){
							a++;
							printf("%dは同色\n",k);
							k--;
						}
						k=end+1;
						while(k<N&&data[k]==color){
							b++;
							printf("%dは同色\n",k);
							k++;
						}
					}
					else{
						if(a+b>=4){
							count+=a+b;
							printf("%d個消えました。通算%d個\n",a+b,count);
						}
						END:
						count=N-count;
						if(count<rensa){
							rensa=count;
							printf("最小値の更新:%dに\n",rensa);
						}
						break;
					}
				}
			}
		}
		if(rensa+1==N){
			rensa++;
		}
		printf("%d\n",rensa);
		scanf("%d",&N);
	}
	return 0;
}