#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;
}
2012第三屆藍橋杯C本科決賽 第五題 “數獨”遊戲
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.