HLOJ482 判断数独_用来位运算练习,状态压缩入门

题面

题目描述
数独是一款智力游戏,现给你一个数独,并需要你验证是否符合规则。 具体规则如下: 每一行都用到1,2,3,4,5,6,7,8,9,位置不限, 每一列都用到1,2,3,4,5,6,7,8,9,位置不限, 每3×3的格子(共九个这样的格子)都用到1,2,3,4,5,6,7,8,9,位置不限, 游戏的过程就是用1,2,3,4,5,6,7,8,9填充空白,并要求满足每行、每列、每个九宫格都用到1,2,3,4,5,6,7,8,9。
输入格式
输入n个数独,你来验证它是否违反规则. 第一行为数独个数, 第二行为第一个数独,之后为第二个,至第n个. 每个数独之间有一个空行
输出格式
若正确则输出”Right”若不正确则输出”Wrong” 输出一个换一行

题解

哈哈哈dp题刷累了来刷水题。
这道题目就是状态压缩入门的。
位运算。
我们知道每一行每一列每一个九宫格都会有1~9的数。
所以我们设一个状态,1代表当前数有,0代表当前数没有,也就是111111111代表九个数都有,000000000代表九个数都没有。
显然,如果九个数在 a [ i ] 都有且只出现一次,那么 ( 1 << a [ i ] ) 一定等于二进制下的111111111.
如果有重复,那么肯定不等于二进制下的111111111.
这就是这道题目的判断方法。
我们还可以想到剪枝方法。(同时可以更好地练习位运算)
如果碰到了一个数 i ,如果当前的状态b右移(9-i)位是偶数,那么就说明没有出现过,如果是奇数,那么就出现过。

code

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int num=0;
    char c=' ';
    bool flag=true;
    for(;c>'9'||c<'0';c=getchar())
    if(c=='-')
    flag=false;
    for(;c>='0'&&c<='9';num=num*10+c-48,c=getchar());
    return flag ? num : -num;
}
const int maxn=10;
int n,full=0;
int a[maxn][maxn];
struct node{
    int x,y;
}direct[maxn];
void yuchuli(){
    for(int i=1;i<=9;i++)
        full=full+(1<<i);
    direct[1]=(node){1,1};
    direct[2]=(node){1,4};
    direct[3]=(node){1,7};
    direct[4]=(node){4,1};
    direct[5]=(node){4,4};
    direct[6]=(node){4,7};
    direct[7]=(node){7,1};
    direct[8]=(node){7,4};
    direct[9]=(node){7,7};
}
void init(){
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            a[i][j]=read();
}
bool check_hang(int k){
    int b=0;
    for(int i=1;i<=9;i++)
        b=b+(1<<a[k][i]);
    return b==full;
}
bool check_lie(int k){
    int b=0;
    for(int i=1;i<=9;i++)
        b=b+(1<<a[i][k]);
    return b==full;
}
bool check_gong(int k){
    int b=0,x=direct[k].x,y=direct[k].y;
    for(int i=x;i<=x+2;i++)
        for(int j=y;j<=y+2;j++)
            b=b+(1<<a[i][j]);
    return b==full;
}
bool work(){
    for(int i=1;i<=9;i++){
        if(!check_hang(i))return false;
        if(!check_lie(i))return false;
        if(!check_gong(i))return false;
    }
    return true;
}
int main(){
    n=read();
    yuchuli();
    for(int _=1;_<=n;_++){
        init();
        if(work())printf("Right\n");
        else printf("Wrong\n");
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_39670434/article/details/80287032