c程序检查有效的数独

时间:2015-07-02 14:57:15

标签: c matrix grid sudoku

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

我的代码在这里

lineAssets

4 个答案:

答案 0 :(得分:1)

我有一个更好的解决方案。我们可以使用整数标志而不是求和。

//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

答案 1 :(得分:0)

您可以检查每个较小的方块是否有效。例如,如果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;

请注意,上面的代码假设整个网格已填满且不为空。如果要检查部分填充的网格,请进行检查。

答案 2 :(得分:0)

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;
}

答案 3 :(得分:0)

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;
}