2012第三屆藍橋杯C本科決賽 第五題 “數獨”遊戲

#include <stdio.h>
int all; // 解答計數

// 保存組別和已設置字符
struct Mar{
	char group;
	char set;
}mar[6][6];

// 將組和行列分離判斷
struct Group{
	int count; // 記錄指針
	char set[6]; // 組內字符
}grp[6];

// 行列是否重複
int lc(int m, int n, char c){ 
	int i;
	for(i=0; i<6; i++){
		if(mar[m][i].set==c)
			return 0;
	}
	for(i=0; i<6; i++){
		if(mar[i][n].set==c)
			return 0;
	}
	return 1;
}

// 處理grp數組,判斷組內是否重複
int gp(char gr, char c){
	int i;
	for(i=0; i<grp[gr-'0'].count; i++){
		if(c==grp[gr-'0'].set[i])
			return 0;
	}
	return 1;
}

// 打印
void print(){
	printf("%d\n", ++all);
	int i, j;
	for(i=0; i<6; i++){
		for(j=0; j<6; j++) printf("%c ", mar[i][j].set);
		printf("\n");
	}
}

// 回溯函數,試探賦值
void set(int m, int n){
	// 滿足輸出
	if(m>5){
		print();
		return;
	}

	int i;

	// 區分固定已設置字符和可變動字符
	if(mar[m][n].set=='0'){
		for(i=0; i<6; i++){
			if(lc(m, n, i+'A') && gp(mar[m][n].group, i+'A')){ // 判斷
				mar[m][n].set=i+'A'; // 試探
				grp[mar[m][n].group-'0'].set[grp[mar[m][n].group-'0'].count++]=mar[m][n].set; // 對應組增加一個字符

				set(m+(n+1)/6, (n+1)%6);
				//mar[m][n].set='0'; //函數退出時必須還願狀態,由於不參與條件判斷,常放於函數後面
				grp[mar[m][n].group-'0'].set[--(grp[mar[m][n].group-'0'].count)]='0'; // 注意組設置字符時會影響下次試探的判斷所以必須還原
			}
		}
		mar[m][n].set='0';
	}
	else set(m+(n+1)/6, (n+1)%6);
}

int main(){
	int i, j, n, t;
	char c;
	for(i=0; i<6; i++){
		for(j=0; j<6; j++){
			mar[i][j].group=getchar();
			mar[i][j].set='0';
		}
		getchar();
	}
	scanf("%d", &n);
	while(n--){
		scanf("%d%c", &t,&c);
		mar[t/10][t%10].set=c;
		grp[mar[t/10][t%10].group-'0'].set[(grp[mar[t/10][t%10].group-'0'].count++)]=c;
	}
	set(0,0);
	if(all==0) printf("0\n");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章