hdu 多校赛 Problem J. Let Sudoku Rotate

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41608020/article/details/81386947

【题目链接】

题目意思

给你一个T,表示案例数量,给次给4*4块的数独,其中每一块数独都是4*4且不重复的,每一块数独只能顺时针反转,求使得数独合法的最少翻转次数。
这里写图片描述
直接暴搜加上可行性剪枝和最优性剪枝即可。
数独的限制较强,可行性剪枝的效果很好。
对每一块数独从上到下,从左到右遍历,每遍历一块,判断是否合法,若不合法就旋转一次再判断。
判断过程如下图所示,假设我们现在搜到了红色块区域,我们要对每一条蓝线和绿线查找有没有相同的元素,若有,则红色块不合法,反之,搜索下一块。
这里flag和book作为一个全局变量,flag作为标记每一次查询都是不同的,book数组标记这个数字在第几次查询中被查询到了。
这里写图片描述

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cctype>
using namespace std;
char s[16][16];
int w[4][4];
int ans, flag, book[16];
void rot(int x,int y)
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
            w[j][3 - i] = s[i + x][j + y];
    }
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
            s[i + x][j + y] = w[i][j];
    }
}
int check(int a, int b)
{
    for (int i = a; i < a + 4; i++)
    {
        flag++;
        for (int j = 0; j < b + 4; j++)
        {
            if (book[s[i][j]] == flag)
                return 0;
            book[s[i][j]] = flag;
        }
    }
    for (int j = b; j < b + 4; j++)
    {
        flag++;
        for (int i = 0; i < a + 4; i++)
        {
            if (book[s[i][j]] == flag)
                return 0;
            book[s[i][j]] = flag;
        }
    }
    return 1;
}
void dfs(int i, int j, int k)
{
    if (i == 4)
    {
        ans = min(ans, k);
        return;
    }
    if (k >= ans)
        return;
    if (j == 4)
        return dfs(i + 1, 0, k);
    for (int t = 0; t < 4; t++)
    {
        if (check(4 * i, 4 * j))
            dfs(i, j + 1, k + t);
        rot(4 * i, 4 * j);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--)
    {
        for (int i = 0; i < 16; i++)
            scanf("%s", s[i]);
        for (int i = 0; i < 16; i++)
        {
            for (int j = 0; j < 16; j++)
            {
                if (isdigit(s[i][j]))
                    s[i][j] -= '0';
                else
                    s[i][j] -= 'A' - 10;
            }
        }
        ans = 999999;
        dfs(0, 0, 0);
        printf("%d\n", ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41608020/article/details/81386947
今日推荐