【问题标题】:c program to check valid sudokuc程序检查有效数独
【发布时间】:2015-07-02 14:57:15
【问题描述】:

我正在编写 c 代码来检查给定的矩阵是否是有效的数独解决方案。 输入将是 n*n 大小的矩阵。 我已经编写了代码来检查行和列,但我没有得到如何验证 sqrt(n)*sqrt(n) 大小的网格。

我的代码在这里

#include<stdio.h>
int main()
{
  int i,j,count=0,sumrow;
  int sumcol;
    int n;
 scanf("%d",&n);
  int arr[n+1][n+1];
  for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
      scanf("%d",&arr[i][j]);
    for(i=1;i<=n;i++)
    {
      sumcol=0;
      for(j=1;j<=n;j++)
      sumcol+=arr[j][i];
      if(sumcol!=(n*(n+1)/2))
        count++;
    }
 for(i=1;i<=n;i++)
  {
    sumrow=0;
    for(j=1;j<=n;j++)
    {
      sumrow+=arr[i][j];
    }
  //    printf("%d\n",sumrow);
    if(sumrow!=(n*(n+1)/2))
      count++;
  }


  //printf("count%d ",count);
  if(count==0)
    printf("yes");
  else
    printf("no");
  return 0;
}

【问题讨论】:

  • 你有什么问题?
  • 我不知道如何验证数独的子网格。例如,对于 9*9 数独,我们有 3*3 的 9 个网格。
  • 在 C 中,我们从 0 开始计数,而不是从 1 开始计数。您的循环应该是 for(i=0;i
  • @steve 我已经分配了 n+1 x n+1 大小的数组

标签: c matrix grid sudoku


【解决方案1】:

这里我有一个更好的解决方案。我们可以使用整数标志来代替 sum。

//read sudoku
for(i=0;i<9;i++)
    for(j=0;j<9;j++)
    {
    scanf("%c",&c);
    a[i][j]=c-'0';
    }
//checking rows
for(i=0;i<9;i++)
    {
    flag=0x0000;
    for(j=0;j<9;j++)
        flag|=1<<(a[i][j]-1);
    if(flag!=0x01FF)
        report("row",i,j-1);
    }

//checking cols
for(j=0;j<9;j++)
    {
    flag=0x0000;
    for(i=0;i<9;i++)
        flag|=1<<(a[i][j]-1);
    if(flag!=0x01FF)
        report("col",i-1,j);
    }
//checking Squares (3x3)
for(si=0;si<3;si++)
    {
    for(sj=0;sj<3;sj++)
        {
        flag=0x0000;
        for(i=0;i<3;i++)
            {
            for(j=0;j<3;j++)
                flag|=1<<(a[si*3+i][sj*3+j]-1);

            }
        if(flag!=0x01FF)
                report("square",si*3+i-1,sj*3+j-1);
        }
    }
printf("\nThe sudoku is correct");

详细说明,您可以visit this link

【讨论】:

    【解决方案2】:

    您可以检查每个较小的方块是否有效。例如,如果n=9 您必须检查每个3 by 3 方块。要检查每个较小的方块,您可以使用包含 10 个元素的数组和检查1 to 9 值是否重复。

    算法如下

      for each of the smaller grids
          if(any of the digit repeats in a smaller grid)
          return 0;
      return 1;//valid
    

    以下是执行相同操作的一些代码

      //A is the grid
      int small=sqrt(n);
      for(int i=0;i<small;i++)
      {
         for(int j=0;j<small;j++)
         {
            int row=small*i;//this will find the corresponding row
            int col=small*j;//this will find the corresponding column
            vector<int> used(10,0)
            for(int p=row; p<row+small; p++) {
                    for(int q=col; q<col+small; q++) 
                    {
                        if(A[p][q]=='0')//0 is not valid
                        return 0;
                        if(used[A[p][q]-'0']==1)//this digit has already been used
                        return 0;
                        if(used[A[p][q]-'0']) return 0;
                        used[A[p][q]-'0']=1;//now this particular digit has occurred and should not occur again
                    }
             }
          }
     }
     //if all's well return 1
     return 1;
    

    请注意,上面的代码假设整个网格被填充并且不为空。如果要检查部分填充的网格,请引入检查。

    【讨论】:

    • used[] 数组的大小是多少
    • @amit. 大小为 10,但您只需要 9(1 到 9)。为了简单起见,我将其保留为 10,避免used[A[p][q]-'0'-1]
    【解决方案3】:
    int main() {
        int a[10][10],i,j,n,k,sum,sum1,sum2,sum3,x,l;
        printf("enter the size N of N*N sudoku\n");
        scanf("%d",&n);
        printf("enter the entries of sudoku row wise \n");
        for (i=1;i<=n;i++) {
            for (j=1;j<=n;j++) {
                scanf("%d",&a[i][j]);
            }
            printf("\n");
        }
        printf("---------------------------------\n\n\n\n");
        printf("the matrix you entered is \n");
        for (i=1;i<=n;i++) {
            for (j=1;j<=n;j++) {
                printf("%d",a[i][j]);
                printf("|");
            }
            printf("\n");
        }
        for (i=1;i<=n;i++) {
            for (k=i;k==i;k++) {
                sum=0;
                for (j=1;j<=n;j++) {
                    sum = sum + a[i][j];
                }
    
                if(sum!=45)
                    x=1;
            }
        }
    
        for (j=1;j<=n;j++) {
            for(k=j;k==j;k++) {
                sum=0;
                for (i=1;i<=n;i++) {
                    sum = sum+a[i][j];
                }
                if (sum!=45)
                    x=1;
            }
        }
    
        for (k=1;k<=3;k++) {
            l = (1+(k-1)*n/3);
            for (i=l;i<=k*n/3;i++) {
                for(j=1;j<=3;j++) {
                    sum1 = sum1+a[i][j];
                }
                for (j=4;j<=6;j++) {
                    sum2 = sum2+a[i][j];
                }
                for (j=7;j<=9;j++) {
                    sum3 = sum3+a[i][j];
                }
            }
            if (sum1!=45||sum2!=45||sum3!=45)
                x=1;
        }
        if (x==1)
            printf("sudoku not correct \n");
        else
            printf("correct sudoku");
    
        return 0;
    }
    

    【讨论】:

    • 我还编写了代码来检查 9 个 3*3 矩阵的数独是否有效
    【解决方案4】:
    bool validateMatrix(int g_iMatrix1[][MAXCOLS],
                         int iROWS,
                         int iCOLS)
    {
        bool bRowUsed[MAXROWS][MAXCOLS]   = {0};
        bool bColUsed[MAXROWS][MAXCOLS]   = {0};
        bool bBlockUsed[MAXROWS][MAXCOLS] = {0};
    
        //Matrix to keep record if current value is already set in current row..
        memset(bRowUsed, false, (MAXROWS) * (MAXCOLS));
    
        //Matrix to keep record if current value is already set in current column..
        memset(bColUsed, false, (MAXCOLS) * (MAXCOLS));
    
        //Matrix to keep record if current value is already set in current block of iSQRT * iSQRT..
        //Lets assume the matrix is of size 9 * 9..
        //So there will be 9 block of 3 * 3..
        //Number the blocks from left to right as 0 to 8..
        //We will be mapping 0 the block to 0th row, 1st block to 1st row, 2nd block to 2nd row and so on..
        memset(bBlockUsed, false, (MAXROWS) * (MAXCOLS));
    
        int iRows = 0,iCols = 0;
        int iSQRT = int(sqrt(MAXCOLS));
    
        for(iRows = 0;iRows < iROWS;iRows++)
        {
            for(iCols = 0;iCols < iCOLS;iCols++)
            {
                if(bRowUsed[iRows][g_iMatrix1[iRows][iCols] - 1] == true)   
                {
                    return false;
                }
                if(bColUsed[g_iMatrix1[iRows][iCols] - 1][iCols] == true)
                {
                    return false;
                }
    
                //Number the blocks from left to right as 1 to 9..
                //We will be mapping 0 the block to 0th row, 1st block to 1st row, 2nd block to 2nd row and so on..
                //((iRows / iSQRT) * iSQRT) + (iCols / iSQRT) will map the block with above logic..
                if(bBlockUsed[((iRows / iSQRT) * iSQRT) + (iCols / iSQRT)][g_iMatrix1[iRows][iCols] - 1] == true)
                {
                    return false;
                }
    
                bRowUsed[iRows][g_iMatrix1[iRows][iCols] - 1] = true;
                bColUsed[g_iMatrix1[iRows][iCols] - 1][iCols] = true;
                bBlockUsed[((iRows / iSQRT) * iSQRT) + (iCols / iSQRT)][g_iMatrix1[iRows][iCols] - 1] = true;
            }
        }
    
        return true;
    }
    

    【讨论】:

    • 感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
    猜你喜欢
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多