トップ 一覧 Farm 検索 ヘルプ RSS ログイン

2000db1.cの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
 // 2000 domestic B
 // 隣が同じ物を見つけたら、すぐに取り去って詰めていくように作った
 // 実際はバックトラックにしないといけない
 
 #include <stdio.h>
 
 #define ON  1
 #define OFF 0
 
 #define X 4
 #define Y 5
 #define N X*Y
 
 // 2次元座標を1次元配列用に変換
 #define p(x,y) ((x)+(y*X))
 
 // 隣の方向の数(8方向)
 #define TONARI 8
 // 隣の場所の座標 上の段、同じ段、下の段
 int tx[TONARI]={-1, 0,+3,-1,+1,-1, 0,+1};
 int ty[TONARI]={-1,-1,-1, 0, 0,+1,+1,+1};
 short c[N]; // 場
 int nokori; // 残った数のカウント
 
 void push(short c[N]);
 void pop(short c[N]);
 
 int sp=0;	 // スタックポインタ
 char st[1000][N]; // スタック
 
 void print(void);
 void check(int z);
 int rearrange(void);
 
 int main(void)
 {
 	short c2[N]; // 一つ前の場
 	int n,i,a,x,y,z;
 	int kotae;
 	
 	scanf("%d", &n);
 	printf("n=%d\n", n);
 	
 	// 読み込み
 	for(z=0; z<n; z++){
 		printf("\n(%d)\n", z+1);
 		for(i=0; i<N; i++){
 			scanf("%d", &a);
 			c[i]=a;
 		}
 		
 		print();
 		puts("-");
 		
 		kotae=N;
 		for(i=0; i<N; i++){
 			printf("start(%d,%d)\n",i%X,i/X);
 			nokori=N;
 			push(c);
 			check(i);
 			pop(c);
 			printf("%d:nokori=%d\n", nokori);
 			if(kotae>nokori){
 				kotae=nokori;
 			}
 		}
 		printf("kotae=%d\n", kotae);
 	}
 	
 	return(0);
 }
 
 void check(int z)
 {
 	int i,x,y,xx,yy;
 	
 //	for(i=1; i<z; i++){
 //		printf(" ");
 //	}
 //	if(z) printf("%d\n", z);
 	
 	if(z<N){
 		x=z%X;
 		y=z/X;
 		for(i=0; i<TONARI; i++){
 			xx=x+tx[i];
 			yy=y+ty[i];
 			if(xx>=0 && yy>=0 && x<X && y<Y){
 				if( c[p(x,y)] && ( c[p(x,y)]==c[p(xx,yy)] ) ){ // 隣で同じ物が見つかったら
 					int count;
 //					printf("(%d,%d)=(%d,%d)=%d\n",x,y,xx,yy,c[p(x,y)]);
 					c[p(x,y)]=c[p(xx,yy)]=0;
 					count=rearrange(); // 0を後に持っていく&残りの枚数を数える
 					if(nokori>count){
 						nokori=count; // 残りの枚数の最小なのを求める
 					}
 //					print();
 					push(c);
 					check(z++);
 					pop(c);
 				}
 			}
 		}
 //		push(c);
 //		check(z++);
 //		pop(c);
 	}
 }
 
 void push(short c[N])
 {
 	int i;
 	for(i=0; i<N; i++){
 		st[sp][i]=c[i];
 	}
 	sp++;
 }
 
 void pop(short c[N])
 {
 	int i;
 	--sp;
 	for(i=0; i<N; i++){
 		c[i]=st[sp][i];
 	}
 }
 
 int rearrange(void)
 {
 	int i,m=0;
 	
 	for(i=0; i<N; i++){
 		if(c[i]!=0){
 			c[m]=c[i];
 			m++;
 		}
 	}
 	for(i=m; i<N; i++){
 		c[i]=0;
 	}
 //	printf("remain:%d\n",m);
 	return(m);
 }
 
 void print(void)
 {
 	int x, y;
 	
 	for(y=0; y<Y; y++){
 		for(x=0; x<X; x++){
 			printf("%d ", c[x+y*X]);
 		}
 		printf("\n");
 	}
 }
 
 /*
 // 解けたかどうかチェック
 int solve(short c[N])
 {
 	int i,sum=0;
 	
 	for(i=0; i<N; i++){
 		sum+=c[i];
 	}
 	if(sum==0){
 		return(ON);
 	}else{
 		return(OFF);
 	}
 }
 
 int stop(short c1[N], short c2[N])
 {
 	int i,flag=OFF;
 	
 	for(i=0; i<N; i++){
 		if(c1[i]!=c2[i]){
 			flag=ON;
 		}
 		c2[i]=c1[i];
 	}
 	return(flag);
 }
 
 
 */