数独C代码 Microsoft Visual C++ 6.0 不胜感激(一定要C程序的不要C++)

数独C代码 Microsoft Visual C++ 6.0 不胜感激(一定要C程序的不要C++),第1张

给,注释改一改,有台湾风格了:

#include < stdioh >

#include < stdlibh >

int sudoku[81] ; // 数独题目阵列

int tempNum[81] ; // 上一次填数位置

int tempSp= 0 ; // 上一次填数位置指标

int startH[81] ; // 列位置的起点

int startV[81] ; // 行位置的起点

int startB[81] ; // 九宫格位置的起点

int addH[9] ; // 列位置的加值

int addV[9] ; // 行位置的加值

int addB[9] ; // 九宫格位置的加值

void init() {

// 参数设定(设定这些参数之后,无论检查行、列、九宫格都方便多了)

int i ;

for(i=0; i<81; i++) {

startH[i]= i/9 9 ; // 列位置的起点

startV[i]= i% 9 ; // 行位置的起点

startB[i]= ((i/9)/3)27+ ((i%9)/3)3 ; // 九宫格位置的起点

}

for(i=0; i<9; i++) {

addH[i]= i ; // 列位置的加值

addV[i]= i9 ; // 行位置的加值

addB[i]= (i/3)9+ (i%3) ; // 九宫格位置的加值

}

}

void printSudoku(int prn) {

// 印出数独题目(阵列内容)

int i ;

for(i=0; i<81; i++) {

printf( "%2d", prn[i]);

if(i%9==8) printf("\n");

}

}

int getNextBlank(int sp) {

// 取得下一个空白的位置

do {

sp++ ;

} while(sp<81 && sudoku[sp]>0) ;

return(sp) ;

}

int check1(int sp, int start, int addnum) {

// 检查指定的行、列、九宫格有没有相同的数字,若有传回 1

int fg= 0, i, sp1 ;

for(i=0; i<9; i++) {

sp1= start+ addnum[i] ;

if(sp!=sp1 && sudoku[sp]==sudoku[sp1]) fg++ ;

}

return(fg) ;

}

int check(int sp) {

// 检查同行、列、九宫格有没有相同的数字,若有传回 1

int fg= 0 ;

if(!fg) fg= check1(sp, startH[sp], addH) ; // 检查同列有没有相同的数字

if(!fg) fg= check1(sp, startV[sp], addV) ; // 检查同行有没有相同的数字

if(!fg) fg= check1(sp, startB[sp], addB) ; // 检查同九宫格有没有相同的数字

return(fg) ;

}

void push(int sp) {

// 将指定的位置放入堆叠中

tempNum[tempSp++]= sp ;

}

int pop() {

// 取出堆叠中的上一个位置

if(tempSp<0) return(-1) ;

else return(tempNum[--tempSp]) ;

}

void tryAns() {

// 测试求解

int sp=getNextBlank(-1) ; // 取得第一个空白的位置开始填入数字

do {

sudoku[sp]++ ; // 将本位置数字加 1

if(sudoku[sp]>9) { // 如果本位置的数字已大於 9 时则回到上一个位置继续测试

sudoku[sp]= 0 ;

sp= pop() ;

} else {

if(check(sp)==0) { // 如果同行、列、九宫格都没有相同的数字,则到下一个空白处继续

push(sp) ; // 当然,如果发现有相同的数字时,就需把原位置的数字加 1(所以本处什麼都不做)

sp= getNextBlank(sp) ;

}

}

} while(sp>=0 && sp<81) ;

}

int main(int argc, char argv[]) {

int j ;

printf( "----------\n");

printSudoku(sudoku) ;

init() ; // 参数设定

tryAns() ; // 测试求解

printf( "----------\n");

printSudoku(sudoku) ;

printf( "----------\n");

}

回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

#include<stdioh>

int map[9][9];

bool isPlace(int count){

int row = count &#47; 9;

int col = count % 9;

int j;

&#47;&#47;同一行

for(j = 0; j < 9; ++j){

if(map[row][j] == map[row][col] && j != col){

return false;

}

}

&#47;&#47;同一列

for(j = 0; j < 9; ++j){

if(map[j][col] == map[row][col] && j != row){

return false;

}

}

&#47;&#47;同一小格

int tempRow = row &#47; 3  3;

int tempCol = col &#47; 3  3;

for(j = tempRow; j < tempRow + 3;++j){

for(int k = tempCol; k < tempCol + 3; ++k){

if(map[j][k] == map[row][col] && j != row && k != col){

return false;

}

}

}

return true;

}

void backtrace(int count){

if(count == 81){

for(int i = 0; i < 9; ++i){

for(int j =  0; j < 9; ++j){

printf("%d ",map[i][j]);

}

printf("&#92;n");

}

return;

}

int row = count &#47; 9;

int col = count % 9;

if(map[row][col] == 0){

for(int i = 1; i <= 9; ++i){

map[row][col] = i;&#47;&#47;赋值

if(isPlace(count)){&#47;&#47;可以放

backtrace(count+1);&#47;&#47;进入下一层

}

}

map[row][col] = 0;&#47;&#47;回溯

}else{

backtrace(count+1);

}

}

int main()

{

char c;

for(int i=0;i<9;i++)

{

for(int j=0;j<9;j++)

{

scanf("%c",&c);

if(c=='')map[i][j]=0;

else map[i][j]=c-'0';

}

scanf("%c",&c);&#47;&#47;接收换行符

}

backtrace(0);

return 0;

}

check()函数的dowhile循环有深层次逻辑错误:当if((rawflag==1)||(colflag==1))为“真”后的某种情况就出现rawflag和colflag不可能同时出现0而导致死循环。写法上if((rawflag==1)||(colflag==1))

{

a[raw][col]=rand()%9+1;

}

else

break;

}

和while((rawflag==1)||(colflag==1));就不协调,好像把if语句删除,把它的体a[raw][col]=rand()%9+1;直接写在do{后才在逻辑上清晰……

我用EXCEL的宏编过,但是算法不太好,简单得可以作出,难得的就不行了

想法如下:

建立一个X(a,b,c,d)的列阵,4个数为(1,2,3)中的一个

a,b表示大的33阵(就是你所说的"区")的位置

c,d表示在特定33阵(特定"区")中的位置

那么每个特定的X表示特定的空格位置

每个X初始都=123456789

X的值表示这个空格可能取的数

然后已经给出的条件的X改为条件给出的数

现在我虽然不知道剩下的空格是哪个数,但是我可以知道特定的空格中不可以是哪个数(按规则)

step1

所以分别检查每个空格

将不可能出现的数字从123456789中删去(比如这个区已经存在1,4,5那么我们把区中其他的空格的1,4,5去掉,变成2,3,6,7,8,9)

这样X的位数就越来越小了

当X的长度等于1的时候那么这个空格就是唯一的了

step2

检查每一个区中的9个数中含有几个1,如果只有1个,那么含有1的哪个空格就是1了,(1-9,依次检验),(行或者列也要分别检验)

step3

检查是不是每个数都小于10,如果不是

检查经过step1和step2后,各个数字有没有变化,如果有,那么重复step1,step2没有的话(说明按刚刚的步骤只能解到这样了)结束循环

我编的只是为了方便帮我解题,太难的做不出,但是用的话可以解出很多数了,人在看一下,很快就解出了

如果一定要编到底的话,我也想过

然后在X中寻找1个2位数,假定2位数中的一个是正确的,然后在按刚刚的步骤,如果结果有矛盾则就是另一个数

希望对你有帮助

哈哈,这简单!数独生成算法?这个还真不好搞,不过我当初写数独游戏的时候随便捣鼓出来过一个,你自己去改改吧,至于这个算法能不能生成所有的数独,我还真没论证过。原理:对一个给出的数独棋盘的所有行或列交换给出的两个数X、Y,数组仍满足数独规则。如给出1、2,则对所有列交换1、2的位置,数组仍满足数独规则。由于对棋盘的演进是随机的,所以相当于随机生成数独棋盘啦。每次演进的次数最好大一点,10次以上吧,以保证每个数都被换过位置。具体代码就不用我写了吧,嘎嘎……追问不用生成所有数独。。只要生成一个唯一解的就好。。。

如果按照您这个算法,交换所有列任意两个数或者多组数就可以生成新的数独了吧。

void readGame (sudukoGrid game) {

cell currentCell = 0;

int inChar = getchar();

while (inChar != EOF) {

if (

((inChar >= MIN_VALUE) && (inChar <= MAX_VALUE)) ||

(inChar == EMPTY_VALUE)

) {

assert (currentCell <= MAX_CELL);

game [currentCell] = inChar;

currentCell++;

}

inChar = getchar();

}

assert (currentCell == (MAX_CELL+1));

}

第一个readgame,谁会别的?

#include<stdioh>

#define N 3

bool rowtest(int n[])

{

int i,j;

int num;

int no_exist=0;

for(i=0;i<NN;i+=N)

{

for(num=1;num<N+1;num++)

{

for(j=i;j<i+N;j++)

{

if(num!=n[j])

no_exist++;

if(no_exist==N)

return 0;

}

no_exist=0;

}

}

return 1;

}

bool coltest(int n[])

{

int i,j;

int num;

int no_exist=0;

for(i=0;i<N;i++)

{

for(num=1;num<N+1;num++)

{

for(j=i;j<i+NN;j+=N)

{

if(num!=n[j])

no_exist++;

if(no_exist==N)

return 0;

}

no_exist=0;

}

}

return 1;

}

void main()

{

int n;

int i;

int j;

char c;

int finish=0;

int realnum=0;

int num[NN]={0};

printf("\n请输入测试的数据组数:\n\n");

scanf("%d",&n);

getchar();

printf("输入的数据只能是1-%d,输入只取前%d个数\n\n",N,NN);

for(i=1;i<=n;i++)

{

printf("第%d组数据如下:\n\n",i);

while(1)

{

c=getchar();

if(c>='1'&&c<=(char)(N+48))

{

num[finish]=c-48;

finish++;

}

realnum++;

if(realnum==N(N+1))

break;

}

for(j=0;j<NN;j++)

{

if(!num[j])

{

printf("输入有误!\n\n");

return;

}

}

if(rowtest(num)&&coltest(num))

printf("yes\n\n");

else

printf("no\n\n");

}

}

由于输入81个数进行检测很麻烦,所以只用了33的数据。你可以将N改为9,即可满足要求。

以上就是关于数独C代码 Microsoft Visual C++ 6.0 //不胜感激(一定要C程序的不要C++)全部的内容,包括:数独C代码 Microsoft Visual C++ 6.0 //不胜感激(一定要C程序的不要C++)、求解数独题,用C语言实现、c语言 随机生成数独等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9678441.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存