编程之美1.15节:构造数独算法-回溯法和置换法
2012-04-16 10:34
274 查看
1. 回溯法-程序
输出结果:
2. 置换的方法
输出结果:
/**回溯法 * 生成数独矩阵 * From 编程之美1.15 */ #include <stdio.h> #include <time.h> /*要生成的数独矩阵个数*/ #define SUDOKU_NUM 1 /** * 函数is_digital_match * 检测sudoku[i][j]上的值是否符合要求 */ int is_digital_match(int sudoku[][9], int i, int j) { int temp = sudoku[i][j]; int p, q; int m, n; for(p=0; p<9; p++) if(p!=i && sudoku[p][j]==temp) return 0; for(p=0; p<9; p++) if(p!=j && sudoku[i][p]==temp) return 0; p = i/3; q = j/3; for(m=p*3; m<p*3+3; m++) for(n=q*3; n<q*3+3; n++) if(m!=i && n!=j && sudoku[m] ==temp) return 0; return 1; } /*输出数独矩阵*/ void sudoku_print(int sudoku[][9]) { int i,j; for(i=0; i<9; i++) { for(j=0; j<9; j++) printf("%4d", sudoku[i][j]); printf("\n"); } } int main(void) { int sudoku[9][9] = {0}; int i, j, temp=0; int k=0, num=0; srand(time(0)); for(i=0; i<9; i++) for(j=0; j<9; j++) sudoku[i][j] = 0; /*通过添加一些随机性,来每次生成不同的数独矩阵*/ /*添加更多随机性,则生成的矩阵将更随即*/ for(i=0; i<9; i++) { temp = rand() % 81; sudoku[temp/9][temp%9] = i+1; } /*回溯法,构造数独矩阵*/ while(1) { i = k/9; j = k%9; while(1) { sudoku[i][j]++; if(sudoku[i][j] == 10) { sudoku[i][j] = 0; --k; break; } else if(is_digital_match(sudoku, i, j) == 1) { ++k; break; } } if(k == 81) { printf("Proper sudoku matrix %d: \n", ++num); sudoku_print(sudoku); if(num >= SUDOKU_NUM) return 0; --k; } } return 0; }
输出结果:
Proper sudoku matrix 1: 2 1 4 5 6 7 9 3 8 3 5 7 1 8 9 2 4 6 6 8 9 4 2 3 1 5 7 4 2 1 3 7 5 8 6 9 8 6 3 2 9 1 4 7 5 7 9 5 6 4 8 3 1 2 5 3 6 8 1 2 7 9 4 1 7 8 9 5 4 6 2 3 9 4 2 7 3 6 5 8 1
2. 置换的方法
/**简单方法 * 快速的构造数独矩阵的算法 * From:编程之美1.15节 * 通过置换,来生成矩阵 */ #include <stdio.h> #include <time.h> int main() { int ini_matrix[3][3]; /*最初的3*3的小格子,用于生成9*9的大格子*/ int sudoku[9][9] = {0}; int i,j; for(i=0; i<3; i++) { for (j=0; j<3; j++) { ini_matrix[i][j] = i*3+j+1; } } /*设置随机数种子*/ srand(time(0)); for(i=0; i<9; i++) { int temp = rand() % 9; j = ini_matrix[i/3][i%3]; ini_matrix[i/3][i%3] = ini_matrix[temp/3][temp%3]; ini_matrix[temp/3][temp%3] = j; } printf("Initial matrix:\n"); for(i=0; i<3; i++) { for (j=0; j<3; j++) { printf("%d\t", ini_matrix[i][j]); } printf("\n"); } /*Put the ini_matrix to the center of sudoku*/ for(i=0; i<3; i++) { for (j=0; j<3; j++) { sudoku[i+3][j+3] = ini_matrix[i][j]; if(i==0) { sudoku[i+4][j] = ini_matrix[i][j]; sudoku[i+5][j+6] = ini_matrix[i][j]; } else if(i==1) { sudoku[i+4][j] = ini_matrix[i][j]; sudoku[i+2][j+6] = ini_matrix[i][j]; } else { sudoku[i+1][j] = ini_matrix[i][j]; sudoku[i+2][j+6] = ini_matrix[i][j]; } if(j==0) { sudoku[i][j+4] = ini_matrix[i][j]; sudoku[i+6][j+5] = ini_matrix[i][j]; } else if(j==1) { sudoku[i][j+4] = ini_matrix[i][j]; sudoku[i+6][j+2] = ini_matrix[i][j]; } else { sudoku[i][j+1] = ini_matrix[i][j]; sudoku[i+6][j+2] = ini_matrix[i][j]; } } } for(i=3; i<6; i++) { for (j=0; j<3; j++) { if(j==0) { sudoku[i-3][j+1] = sudoku[i][j]; sudoku[i+3][j+2] = sudoku[i][j]; } else if(j==1) { sudoku[i-3][j+1] = sudoku[i][j]; sudoku[i+3][j-1] = sudoku[i][j]; } else { sudoku[i-3][j-2] = sudoku[i][j]; sudoku[i+3][j-1] = sudoku[i][j]; } } } for(i=3; i<6; i++) { for (j=6; j<9; j++) { if(j==6) { sudoku[i-3][j+1] = sudoku[i][j]; sudoku[i+3][j+2] = sudoku[i][j]; } else if(j==7) { sudoku[i-3][j+1] = sudoku[i][j]; sudoku[i+3][j-1] = sudoku[i][j]; } else { sudoku[i-3][j-2] = sudoku[i][j]; sudoku[i+3][j-1] = sudoku[i][j]; } } } printf("Final matrix:\n"); for(i=0; i<9; i++) { for (j=0; j<9; j++) { printf("%d\t", sudoku[i][j]); } printf("\n"); } return 0; }
输出结果:
Initial matrix: 3 5 7 2 6 4 8 9 1 Final matrix: 1 8 9 7 3 5 4 2 6 7 3 5 4 2 6 1 8 9 4 2 6 1 8 9 7 3 5 8 9 1 3 5 7 2 6 4 3 5 7 2 6 4 8 9 1 2 6 4 8 9 1 3 5 7 9 1 8 5 7 3 6 4 2 5 7 3 6 4 2 9 1 8 6 4 2 9 1 8 5 7 3
相关文章推荐
- 编程之美1.15构造数独-----回溯法java版
- 编程之美1.15构造数独---置换法java版
- 编程之美:第一章 1.15构造数独
- 构造数独 算法及代码实现
- 关于《编程之美》中构造数独问题的小结
- 【算法】回溯法实现0-1背包【原创技术】
- 操作系统--页面置换算法(先进先出算法,最近最久未使用算法,最佳置换算法)--JAVA实现
- 【算法总结-回溯法】回溯与八皇后
- 【打CF,学算法——二星级】CodeForces 417C Football(构造)
- FIFO、LRU、OPT这三种置换算法的缺页次数
- FIFO、LRU、OPT这三种置换算法的缺页次数
- 用java语言实现的巡回置换算法
- 构造数组的MaxTree(每日一道算法题)
- 算法java实现--回溯法--批处理作业调度问题
- 算法复习笔记(回溯法,分支限界法)
- FIFO、LRU、OPT这三种置换算法的缺页次数
- 先进先出(FIFO)置换算法
- 五大常用算法之四:回溯法
- 图论中最小生成树构造算法之Prim算法和Kruskal算法
- 数独游戏(sudoku)算法 回溯+剪枝