题目描述
众所周知,数独是一款简单上手(划掉)且极易打发时间的游戏,fishfloss喜欢玩数独,虽然自己很菜。
数独的具体规则是这样的:
需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一宫(3x3)内的数字均含1-9并不重复。
例如 :
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 5
就是一个合法的数独的解
而
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 4
则不是
那么下面给出数独盘面,来判断一下它是否是数独的合法解吧
输入描述:
输入共9行,每行9个数,代表数独盘面
输出描述:
一行,如果输入是数独的合法解,则输出YES
反之输出NO
示例1
输入
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 5
输出
YES
示例2
输入
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 4
输出
NO
说明
对于宫9,行9及列9,显然有重复的4,故不满足合法解
解题思路:
每一行、每一列、每一宫都不可以有重复的数字,那么可以用计数排序的方法对其进行判断。对行与列的判断比较简单,行的判断甚至可以一边输入一边判断,对列的判断只要交换一下输入的顺序即可。对每一宫的判断是这道题的难点,但是其实想清楚就很简单了。我的做法是将行与列的输入分成三份,在这基础上在写两个for循环进行输入判断。
需要注意的是,用于判断的数组每次判断完之后需要清空,为洗一次判断做准备。
代码如下:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[9][9];
int main()
{
int i,j,k;
int flag=0;
int b[10];
memset(b,0,sizeof(b));
//输入+判断每一行
for(i=0;i<9;i++){
for(j=0;j<9;j++){
cin>>a[i][j];
b[a[i][j]]++;
}
for(k=1;k<10;k++){
if(b[k]!=1){
flag=1;
break;
}
}
memset(b,0,sizeof(b));
}
//判断每一列
for(j=0;j<9;j++){
for(i=0;i<9;i++) b[a[i][j]]++;
for(k=1;k<10;k++){
if(b[k]!=1){
flag=1;
break;
}
}
memset(b,0,sizeof(b));
}
//判断每一宫
for(i=0;i<9;i=i+3){
for(j=0;j<9;j=j+3){
//对每一宫内的数判断
for(int i2=i;i2<i+3;i2++){
for(int j2=j;j2<j+3;j2++){
b[a[i2][j2]]++;
}
}
for(k=1;k<10;k++){
if(b[k]!=1){
flag=1;
break;
}
}
memset(b,0,sizeof(b));
if(flag==1)break;
}
if(flag==1)break;
}
if(flag==1)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
return 0;
}