解算数独

  本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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值