本c程序为数独的一款分支图解器,只适用于娱乐。
之所以去写作弊器,并不是我不会,只是为了解出应有的答案,
详情如下:
第一个子函数的作用是图像的输出,在主函数中已经对数据进行了初始化,在没有输入数据时
输出的是每个空对应的坐标,当输入数据时函数输出的是刚刚在该位置上输入的数。
首先考虑,为了可以更清楚的输入数据并显示出输入后的图像,程序如下:
// 图像
void h (int a1[][9])
{
int i,j;
printf("\t");
for(i=0;i<9;i++) printf("\t %d",i);
printf("\n");
for(i=0;i<9;i++)
{ printf("\t%d",i);
for(j=0;j<9;j++)
if(a1[i][j]>0) printf("\t %d",a1[i][j]);
else printf("\t(%d,%d)",i,j);
printf("\n");
}
}
效果如下:
没有输入时
0 1 2 3 4 5 6 7 8
0 (0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6) (0,7) (0,8)
1 (1,0) (1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8)
2 (2,0) (2,1) (2,2) (2,3) (2,4) (2,5) (2,6) (2,7) (2,8)
3 (3,0) (3,1) (3,2) (3,3) (3,4) (3,5) (3,6) (3,7) (3,8)
4 (4,0) (4,1) (4,2) (4,3) (4,4) (4,5) (4,6) (4,7) (4,8)
5 (5,0) (5,1) (5,2) (5,3) (5,4) (5,5) (5,6) (5,7) (5,8)
6 (6,0) (6,1) (6,2) (6,3) (6,4) (6,5) (6,6) (6,7) (6,8)
7 (7,0) (7,1) (7,2) (7,3) (7,4) (7,5) (7,6) (7,7) (7,8)
8 (8,0) (8,1) (8,2) (8,3) (8,4) (8,5) (8,6) (8,7) (8,8)
有输入时
0 1 2 3 4 5 6 7 8
0 (0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6) (0,7) (0,8)
1 (1,0) (1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8)
2 (2,0) (2,1) (2,2) (2,3) (2,4) (2,5) (2,6) (2,7) (2,8)
3 (3,0) (3,1) (3,2) (3,3) (3,4) (3,5) (3,6) (3,7) (3,8)
4 (4,0) (4,1) (4,2) (4,3) (4,4) (4,5) (4,6) (4,7) (4,8)
5 (5,0) (5,1) (5,2) (5,3) (5,4) 7 (5,6) (5,7) (5,8)
6 (6,0) (6,1) (6,2) (6,3) (6,4) (6,5) (6,6) (6,7) (6,8)
7 (7,0) (7,1) (7,2) (7,3) (7,4) (7,5) (7,6) (7,7) (7,8)
8 (8,0) (8,1) (8,2) (8,3) (8,4) (8,5) (8,6) (8,7) (8,8)
等二个子函数的作用是让用户输入数据并对用户输入的数据进行检验是否符合数独的规则,如果错误将会给出错误原因的文本提示并让用户重新输入数据。
(注:提示文本分两种情况。1.输入的数据超出范围。 2.输入的坐标是重复的。)
其次是,判断输入的数据是否有效,并输出提示让用户,程序如下:
//输入
void fun (int a1[][9] ,int b[][3] ,int *p)
{
int i,j,i1=0,i2,t=1,t1=1;
int k1,k2;
for(;;)
{
printf("\t");
for(i=0;i<9;i++) printf("\t %d",i);
printf("\n");
for(i=0;i<9;i++)
{ printf("\t%d",i);
for(j=0;j<9;j++) printf("\t(%d,%d)",i,j);
printf("\n");
}
if(*p<0)
if(t1==1)
{
printf("请问本数独有几个数\n");
scanf("%d",p);
if(*p==0)
{
t1=0;
system("cls");
printf("输入错误\n按Enter重新输入");
getch();
system("cls");
}
else t1=1;
}
else
{
printf("请问本数独有几个数\n");
scanf("%d",p);
if(*p==0)
{
t1=0;
system("cls");
printf("输入错误\n按Enter重新输入");
getch();
system("cls");
}
else t1=1;
}
if(t1==0)
{ t1=1; *p=-1; continue; }
system("cls");
//---------------------------------------------------------------------
for(;i1<*p;i1++)
{
h(a1);
t1=-1;
if(t==1)
{
printf("请输入第%d个数和位置\n",i1+1);
printf("位置为上图的坐标\n");
if(i1==0) printf("注:先输入位置再输入数\n");
scanf("%d %d %d",&b[i1][0],&b[i1][1],&b[i1][2]);
k1=b[i1][0];
k2=b[i1][1];
a1[b[i1][0]][b[i1][1]]=b[i1][2];
if(!(b[i1][2]>=1&&b[i1][2]<=9))
{
system("cls");
printf("你输入的值错误\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=0;
getch();
t=0;
break;
}
for(i2=0;i2<i1;i2++)
{
if(k1==b[i2][0]&&k2==b[i2][1])
{
system("cls");
printf("你输入的坐标是重复的\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=b[i1-1][2];
getch();
t=0;
}
system("cls");
if(t==0) break;
}
if(t==0) break;
}
else
{
t=1;
printf("请重新输入第%d个数和位置\n",i1+1);
printf("位置为上图的坐标\n");
scanf("%d %d %d",&b[i1][0],&b[i1][1],&b[i1][2]);
k1=b[i1][0];
k2=b[i1][1];
a1[b[i1][0]][b[i1][1]]=b[i1][2];
if(!(b[i1][2]>=1&&b[i1][2]<=9))
{
system("cls");
printf("你输入的值错误\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=0;
getch();
t=0;
break;
}
for(i2=0;i2<i1;i2++)
{
if(k1==b[i2][0]&&k2==b[i2][1])
{
system("cls");
printf("你输入的坐标是重复的\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=b[i1-1][2];
getch();
t=0;
}
system("cls");
if(t==0) break;
}
if(t==0) break;
t=1;
}
system("cls");
}
if(t==0) continue;
if(i1==*p)
{ h(a1); break; }
}
}
等三个子函数是运用暴力计算的方法给数独循环附值并找到符合条件的数,并且在最后把值放
入到数独。
考虑到各行各列和每个九宫格的规则,才使用这种方法。 程序如下:
// 判断和赋值
void f (int a1[][9] ,int b[][3] ,int X )
{
int i,j,i1,t=-1,T=1;
int k0,k1,k2,k3,k4;
for(;;)
{
// 赋值
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
for(i1=0;i1<X;i1++)
{
if((i==b[i1][0])&&(j==b[i1][1])) continue;
else
{
t=rand()%10;
for(;t==0;) t=rand()%10;
a1[i][j]=t;
}
}
}
// 判断 不为0
for(k0=0;k0<9;k0++)
{
for(k1=0;k1<9;k1++)
{
if(a1[k0][k1]==0) T=0;
else T=1;
}
if(T==0) break;
}
if(T==0) break;
// 行
for(k0=0;k0<9;k0++)
{
for(k1=0;k1<9;k1++)
{
for(k2=k1+1;k2<9;k2++)
{
if(a1[k0][k1]==a1[k0][k2]) { T=0; break;}
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) continue;
// 列
for(k0=0;k0<9;k0++)
{
for(k1=0;k1<9;k1++)
{
for(k2=k1+1;k2<9;k2++)
{
if(a1[k1][k0]==a1[k2][k0]) { T=0; break;}
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) continue;
for(k0=1;k0<=3;k0++)
{
// 1行 区块
for(k1=3*(k0-1);k1<3*k0;k1++)
{
for(k2=0;k2<3;k2++)
{
for(k3=3*(k0-1);k3<3*k0;k3++)
{
for(k4=0;k4<3;k4++)
{
if(a1[k1][k2]==a1[k3][k4]) { T=0; break; }
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
// 2行 区块
for(k1=3*(k0-1);k1<3*k0;k1++)
{
for(k2=3;k2<6;k2++)
{
for(k3=3*(k0-1);k3<3*k0;k3++)
{
for(k4=3;k4<6;k4++)
{
if(a1[k1][k2]==a1[k3][k4]) { T=0; break; }
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
// 3行 区块
for(k1=3*(k0-1);k1<3*k0;k1++)
{
for(k2=6;k2<9;k2++)
{
for(k3=3*(k0-1);k3<3*k0;k3++)
{
for(k4=6;k4<9;k4++)
{
if(a1[k1][k2]==a1[k3][k4]) { T=0; break; }
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) continue;
if(T==1) break;
}
}
最后是主函数对各项函数的调用,使的各子函数之间可以相互联系起来构成这整个函数,并使这个函数有了解算数独的功能。
程序如下:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
/*
#include <stdilb.h>
#include <windous.h>
system("cle"); 清屏
system("puaes");
void srand(unsigned seed);
rand(); 随机数
*/
// 图像
void h (int a1[][9])
{
int i,j;
printf("\t");
for(i=0;i<9;i++) printf("\t %d",i);
printf("\n");
for(i=0;i<9;i++)
{ printf("\t%d",i);
for(j=0;j<9;j++)
if(a1[i][j]>0) printf("\t %d",a1[i][j]);
else printf("\t(%d,%d)",i,j);
printf("\n");
}
}
// 输入
void fun (int a1[][9] ,int b[][3] ,int *p)
{
int i,j,i1=0,i2,t=1,t1=1;
int k1,k2;
for(;;)
{
printf("\t");
for(i=0;i<9;i++) printf("\t %d",i);
printf("\n");
for(i=0;i<9;i++)
{ printf("\t%d",i);
for(j=0;j<9;j++) printf("\t(%d,%d)",i,j);
printf("\n");
}
if(*p<0)
if(t1==1)
{
printf("请问本数独有几个数\n");
scanf("%d",p);
if(*p==0)
{
t1=0;
system("cls");
printf("输入错误\n按Enter重新输入");
getch();
system("cls");
}
else t1=1;
}
else
{
printf("请问本数独有几个数\n");
scanf("%d",p);
if(*p==0)
{
t1=0;
system("cls");
printf("输入错误\n按Enter重新输入");
getch();
system("cls");
}
else t1=1;
}
if(t1==0)
{ t1=1; *p=-1; continue; }
system("cls");
//---------------------------------------------------------------------
for(;i1<*p;i1++)
{
h(a1);
t1=-1;
if(t==1)
{
printf("请输入第%d个数和位置\n",i1+1);
printf("位置为上图的坐标\n");
if(i1==0) printf("注:先输入位置再输入数\n");
scanf("%d %d %d",&b[i1][0],&b[i1][1],&b[i1][2]);
k1=b[i1][0];
k2=b[i1][1];
a1[b[i1][0]][b[i1][1]]=b[i1][2];
if(!(b[i1][2]>=1&&b[i1][2]<=9))
{
system("cls");
printf("你输入的值错误\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=0;
getch();
t=0;
break;
}
for(i2=0;i2<i1;i2++)
{
if(k1==b[i2][0]&&k2==b[i2][1])
{
system("cls");
printf("你输入的坐标是重复的\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=b[i1-1][2];
getch();
t=0;
}
system("cls");
if(t==0) break;
}
if(t==0) break;
}
else
{
t=1;
printf("请重新输入第%d个数和位置\n",i1+1);
printf("位置为上图的坐标\n");
scanf("%d %d %d",&b[i1][0],&b[i1][1],&b[i1][2]);
k1=b[i1][0];
k2=b[i1][1];
a1[b[i1][0]][b[i1][1]]=b[i1][2];
if(!(b[i1][2]>=1&&b[i1][2]<=9))
{
system("cls");
printf("你输入的值错误\n按Enter重新输入\n");
a1[b[i1][0]][b[i1][1]]=b[i1-1][2];
a1[b[i1][0]][b[i1][1]]=0;
getch();
t=0;
break;
}
for(i2=0;i2<i1;i2++)
{
if(k1==b[i2][0]&&k2==b[i2][1])
{
system("cls");
printf("你输入的坐标是重复的\n按Enter重新输入\n");
getch();
t=0;
}
system("cls");
if(t==0) break;
}
if(t==0) break;
t=1;
}
system("cls");
}
if(t==0) continue;
if(i1==*p)
{ h(a1); break; }
}
}
// 判断和赋值
void f (int a1[][9] ,int b[][3] ,int X )
{
int i,j,i1,t=-1,T=1;
int k0,k1,k2,k3,k4;
for(;;)
{
// 赋值
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
for(i1=0;i1<X;i1++)
{
if((i==b[i1][0])&&(j==b[i1][1])) continue;
else
{
t=rand()%10;
for(;t==0;) t=rand()%10;
a1[i][j]=t;
}
}
}
// 判断 不为0
for(k0=0;k0<9;k0++)
{
for(k1=0;k1<9;k1++)
{
if(a1[k0][k1]==0) T=0;
else T=1;
}
if(T==0) break;
}
if(T==0) break;
// 行
for(k0=0;k0<9;k0++)
{
for(k1=0;k1<9;k1++)
{
for(k2=k1+1;k2<9;k2++)
{
if(a1[k0][k1]==a1[k0][k2]) { T=0; break;}
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) continue;
// 列
for(k0=0;k0<9;k0++)
{
for(k1=0;k1<9;k1++)
{
for(k2=k1+1;k2<9;k2++)
{
if(a1[k1][k0]==a1[k2][k0]) { T=0; break;}
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) continue;
for(k0=1;k0<=3;k0++)
{
// 1行 区块
for(k1=3*(k0-1);k1<3*k0;k1++)
{
for(k2=0;k2<3;k2++)
{
for(k3=3*(k0-1);k3<3*k0;k3++)
{
for(k4=0;k4<3;k4++)
{
if(a1[k1][k2]==a1[k3][k4]) { T=0; break; }
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
// 2行 区块
for(k1=3*(k0-1);k1<3*k0;k1++)
{
for(k2=3;k2<6;k2++)
{
for(k3=3*(k0-1);k3<3*k0;k3++)
{
for(k4=3;k4<6;k4++)
{
if(a1[k1][k2]==a1[k3][k4]) { T=0; break; }
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
// 3行 区块
for(k1=3*(k0-1);k1<3*k0;k1++)
{
for(k2=6;k2<9;k2++)
{
for(k3=3*(k0-1);k3<3*k0;k3++)
{
for(k4=6;k4<9;k4++)
{
if(a1[k1][k2]==a1[k3][k4]) { T=0; break; }
else T=1;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) break;
}
if(T==0) continue;
if(T==1) break;
}
}
// 主程序:
void main()
{
int a1[9][9]={0},b[100][3]={0};
int i,j,X=-1;
printf("本程序只是解算结果,无其它作用。\n按Enter进入。\n");
getch();
system("cls");
// 输入:
fun (a1,b,&X);
// 判断和赋值:
f(a1,b,X);
// 效果检验 :
printf("\n解算结果如下\n");
h(a1);
getch();
}