发在校内上了,想想还是贴到这来更适合些:
看《编程之美》,没什么事,自己写了个数独程序
回溯非递归,贴上来吧
怕是过些时候就没了。
不知道从linux下贴过来有没有贴错...
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <string.h>
//generate a maxtrix whose volumn is (m*m) * (m*m)
int ** generate_sudoku( int m )
{
if( m < 1 )
printf("m must be greater than zero!/n");
int n = m * m;
int * num_used_in_cur_row = new int [n];
int ** num_used_in_cur_unit_matrix = new int* [m];
int * candidate_num_row_idx_array = new int [n];
int ** sudoku_matrix = new int* [n];
int i, j;
for( i = 0; i < m; i++ )
{
num_used_in_cur_unit_matrix[i] = new int [n];
memset( num_used_in_cur_unit_matrix[i], 0, ( sizeof( int) * n) );
}
//initial the sudoku_matrix
//fill each column with num 1-n randmonly
//the conflict in each row and unit matrix, if any, will be resolved later
for( i = 0; i < n; i++ )
{
sudoku_matrix[i] = new int [n];
memset( sudoku_matrix[i], 0, ( sizeof( int) * n) );
}
srand( time( NULL ) );
int row, column;
for( column = 0; column < n; column++ )
{
int num = 1;
row = 0;
for( num; num <= n; num++ )
{
row = rand() % n;
//use open-address way to find an available position for current num
while( sudoku_matrix[row][column] != 0 )
row = (row + 1) % n;
sudoku_matrix[row][column] = num;
}
}
printf(" The initial sudoku-matrix is:/n" );
for( i = 0; i < n; i++ )
{
for( j = 0; j < n; j++ )
printf( "%d/t", sudoku_matrix[i][j] );
printf("/n");
}
//deal with the conflict in each row and unit matrix now
//using backtracing algorithm
//candidate_num_row_idx_array keeps the info for each column while trace back
//the complexity should be O( n*n*n ) but I didn't prove it accuratlly
int cur_unit_matrix_row = 0;
for( row = 0; row < n; row++ )
{
column = 0;
//initial job for resolve this row
memset( num_used_in_cur_row, 0, ( sizeof( int ) * n ) );
if( row == cur_unit_matrix_row + m )
{
for( i = 0; i < m; i++ )
memset( num_used_in_cur_unit_matrix[ i ], 0, ( sizeof( int ) * n ) );
cur_unit_matrix_row = row;
}
for( i = 0; i < n; i++ )
candidate_num_row_idx_array[ i ] = row;
//resolve conflict now
while( column < n )
{
int unit_matrix_idx = column / m;
int candidate_row = candidate_num_row_idx_array[ column ];
//find a right num for this position from this column
while( candidate_row < n && /
( num_used_in_cur_row[ sudoku_matrix[candidate_row][column] - 1 ] != 0 || /
num_used_in_cur_unit_matrix[unit_matrix_idx][ sudoku_matrix[candidate_row][column] - 1 ] != 0)
)
{
candidate_row++;
}
// we need to trace back and try another way if current situation is locked
if( candidate_row >= n )
{
//trace back current column's status
candidate_num_row_idx_array[ column ] = row;
//deal with the former column
column--;
assert( column >= 0 );
unit_matrix_idx = column / m;
//mark back the candidate num unused
num_used_in_cur_row[ sudoku_matrix[candidate_num_row_idx_array[column]][column] - 1 ] = 0;
num_used_in_cur_unit_matrix[unit_matrix_idx][ sudoku_matrix[ candidate_num_row_idx_array[column] ][column] - 1 ] = 0;
//re-search from the next element
candidate_num_row_idx_array[ column ]++;
continue;
}
candidate_num_row_idx_array[ column ] = candidate_row;//record the current candidate row index
//mark this num used
num_used_in_cur_row[ sudoku_matrix[candidate_row][column] - 1] = 1;
num_used_in_cur_unit_matrix[unit_matrix_idx][ sudoku_matrix[candidate_row][column] - 1 ] = 1;
column++;
}
//Only exchange element here for efficiency
for( column = 0; column < n; column++ )
{
if( row != candidate_num_row_idx_array[ column ] )
{
int temp = sudoku_matrix[row][column];
sudoku_matrix[row][column] = sudoku_matrix[ candidate_num_row_idx_array[column] ][column];
sudoku_matrix[ candidate_num_row_idx_array[column] ][column] = temp;
}
// printf( "%d/t", sudoku_matrix[row][column] );
}
// printf( "/n" );
}
delete [] num_used_in_cur_row;
for( i = 0; i < m; i++ )
delete [] num_used_in_cur_unit_matrix[i];
delete [] num_used_in_cur_unit_matrix;
delete [] candidate_num_row_idx_array;
return sudoku_matrix;
}
int main()
{
int m, n;
printf("Pls input the unit matrix dimension of sudoku you want: ");
scanf("%d", &m);
n = m * m;
int ** sudoku_matrix = generate_sudoku( m );
printf(" The sudoku-matrix is:/n" );
int i, j;
for( i = 0; i < n; i++ )
{
for( j = 0; j < n; j++ )
printf( "%d/t", sudoku_matrix[i][j] );
printf("/n");
}
for( i = 0; i < n; i++ )
delete [] sudoku_matrix[i];
delete [] sudoku_matrix;
return 0;
}
运行结果:
Pls input the unit matrix dimension of sudoku you want: 3
The initial sudoku-matrix is:
8 1 1 9 3 5 5 3 6
3 7 5 5 5 6 8 2 1
9 8 2 4 4 2 1 6 4
1 4 3 6 6 7 2 1 5
5 9 8 7 7 9 7 8 7
6 2 6 3 8 4 9 9 8
4 6 4 8 1 1 6 4 9
2 3 7 1 9 8 4 7 3
7 5 9 2 2 3 3 5 2
The sudoku-matrix is:
8 1 5 9 3 6 2 4 7
3 7 2 5 4 1 8 6 9
9 4 6 7 8 2 1 3 5
1 8 3 6 7 9 5 2 4
5 9 4 3 2 8 7 1 6
6 2 7 4 1 5 9 8 3
4 6 8 1 5 7 3 9 2
2 5 9 8 6 3 4 7 1
7 3 1 2 9 4 6 5 8