题目
WA Jiana在ACM队的代号是188(kg)。188很喜欢边吃边捣鼓各种小游戏。
近两天,她听说软工班的短学期在做贪吃蛇小游戏,这让贪吃的她很心动。她也很想做一个这样的小游戏,但是贪吃蛇实在是太高端了她不会写,于是她挑了一个更简单的游戏——数独。数独的游戏规则如下:用19内的数字填充一个9×9的矩阵,要求填充完后每行都恰好用到19中的每个一个数字(位置不限),每列也恰好用到19中的每个数字(位置不限)。同时,每个3×3的九宫格(9×9的矩阵可恰好划分出9个九宫格,即下图的5个黄色区域和4个白色区域)也要恰好用到19中的每个数字(位置不限)。总是WA的她发现就算是数独对她来说都太困难了,她写的数独判断程序总是一言不合就WA掉,这让她很苦恼(因为写程序大大占用了她吃东西的时间),于是她想请聪明的你来帮她写一个数独判定程序,好让她能把更多的时间拿来吃东西。
数独判定程序主要判断数独是否正确。
如下是一个正确的数独:
5 8 1 4 9 3 7 6 2
9 6 3 7 1 2 5 8 4
2 7 4 8 6 5 9 3 1
1 2 9 5 4 6 3 7 8
4 3 6 1 8 7 2 9 5
7 5 8 3 2 9 1 4 6
8 9 2 6 7 1 4 5 3
6 1 5 9 3 4 8 2 7
3 4 7 2 5 8 6 1 9
Input
首先输入一个T,代表T组测试数据。
对于每组测试数据,输入是一个9×9的矩阵,代表填充好后的数独。矩阵中的数字均为1~9的整数。
每组输入之间有一个空行。
Output
对于每组测试数据,输出一行,若正确则为”Right”,否则为”Wrong”。
题解:
首先由数独的规律可知,数独的每行每列每个九宫格都必须独立出现1到9,否则就不是数独。所以,我们可以遍历数独的行和列以及九宫格,如果这些范围中不符合同时出现1到9的数字,则不合法。
对于九宫格的遍历可以如下图所示:
具体代码
#include<stdio.h>
int main()
{
int t,i,j,k,n,m,flag,vis1[20]={0},vis2[20]={0},a[20][20];
scanf("%d",&t);
while(t--)
{
flag=1;
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
scanf("%d",&a[i][j]);//输入
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
vis1[a[i][j]]++;//统计行中出现的数字
vis2[a[j][i]]++;//统计列中出现的数字
}
for(k=1;k<=9;k++)
{//从1到9遍历各个vis数组
if(!vis1[k]||!vis2[k])//如果其中某个数字没有访问过
flag=0;//则不合法
vis1[k]=vis2[k]=0;//记得要将vis数组清零,以便下次的统计
}
}
n=0,m=0;//用于九宫格的遍历,n代表行的变化,m代表列的变化
while(n<9)
{
for(i=1+n;i<=3+n;i++)
for(int j=1+m;j<=3+m;j++)
vis1[a[i][j]]++;//统计各个数字的出现
for(k=1;k<=9;k++)
{
if(!vis1[k])//如果有个数字没出现则不合法
flag=0;
vis1[k]=0;//记得清零,以便下次统计
}
m+=3;
if(m==9)
{//如果列变化量m=9,相当于超出了列的范围,我们从头开始计数
//并且将行变化量n加3
m=0;
n+=3;
}//最后行变化量会等于9,退出while循环,恰好遍历完整个数独
}
printf(flag==1?"Right\n":"Wrong\n");//输出是否合法
}
return 0;
}