Sudoku(数独缩小版(4*4))

时间:2021-03-01 02:41:44

题目来源https://vjudge.net/problem/HDU-5547
【题意】
在含*字符处填入数字,符合数独要求。
【思路】
模板题。dfs+暴力枚举
【代码】

#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
int a[9][9];
bool legal(int x, int y,int v)
{
    for(int i = 0; i < 4; i++)
    {
        if(i != x && a[i][y] == v)//同一行
            return 0;
        if(i != y && a[x][i] == v)//同一列
            return 0;
    }
    int xx = x/2*2;
    int yy = y/2*2;
    for(int i = xx; i <xx+2; i++)//同一块
        for(int j = yy; j <yy+2; j++)
            if(i != x && j != y && a[i][j] == v)
                return 0;
    return 1;
}
void dfs(int k,int &t)
{
    if(k == 16)//若是没有flag标记已找到的话,很容易超时。但是不标记也过了。
    {
        printf("Case #%d:\n",t++);
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
                printf("%d",a[i][j]);
            printf("\n");
        }
        return;
    }
    int x = k/4;
    int y = k%4;
    if(a[x][y] ==0)
    {
        for(int i = 1; i <= 4; i++)
        {
            a[x][y] =i;
            if(legal(x, y, a[x][y]))
                dfs(k+1,t);
        }
        a[x][y] = 0;
    }
    else
        dfs(k+1,t);
}
int main()
{
    int T,t=1;
    scanf("%d",&T);
    while(T--)
    {
        char str[10];
        for(int i = 0; i < 4; i ++)
        {
            scanf("%s",str);
            for(int j = 0; j < 4; j++)
                a[i][j]=str[j]=='*'?0:str[j]-'0';
        }
        dfs(0,t);
    }
}