Hdu 6341 Problem J. Let Sudoku Rotate 暴力dfs+剪枝

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

Problem J. Let Sudoku Rotate

Input file: standard input
Output file: standard output
Time limit: 2 seconds
Memory limit: 256 mebibytes

Problem Description

Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the world.
In this problem, let us focus on puzzles with 16×16 grids, which consist of 4×4 regions. The objective is to fill the whole grid with hexadecimal digits, i.e. 0123456789ABCDEF, so that each column, each row, and each region contains all hexadecimal digits. The figure below shows a solved sudoku.
Yesterday, Kazari solved a sudoku and left it on the desk. However, Minato played a joke with her - he performed the following operation several times.
* Choose a region and rotate it by 90 degrees counterclockwise.
She burst into tears as soon as she found the sudoku was broken because of rotations.
Could you let her know how many operations her brother performed at least?

Input

The first line of the input contains an integer T (1≤T≤103) denoting the number of test cases.
Each test case consists of exactly 16 lines with 16 characters each, describing a broken sudoku.

Output

For each test case, print a non-negative integer indicating the minimum possible number of operations.

Sample Input Sample Output
1
681D5A0C9FDBB2F7
0A734B62E167D9E5
5C9B73EF3C208410
F24ED18948A5CA63
39FAED5616400B74
D120C4B7CA3DEF38
7EC829A085BE6D51
B56438F129F79C2A
5C7FBC4E3D08719F
AE8B1673BF42A58D
60D3AF25619C30BE
294190D8EA57264C
C7D1B35606835EAB
AF52A1E019BE4306
8B36DC78D425F7C9
E409492FC7FA18D2
5

暴力dfs,对每个矩阵的旋转次数进行枚举。

搜索过程当中,可以利用数独的性质剪枝,也可以利用迭代加深,当当前花费多于答案时直接return.


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <assert.h>
#define pb push_back 
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
typedef pair<int,int> pp;
const int maxn=25,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
int r[maxn][maxn],c[maxn][maxn];
int x11[16]={1,1,1,1,5,5,5,5,9,9,9,9,13,13,13,13},
    x22[16]={4,4,4,4,8,8,8,8,12,12,12,12,16,16,16,16},
    y11[16]={1,5,9,13,1,5,9,13,1,5,9,13,1,5,9,13},
    y22[16]={4,8,12,16,4,8,12,16,4,8,12,16,4,8,12,16};
int a[maxn][maxn][4];
char s[maxn][maxn];
int ans;

void rotate(int id,int re) {
/*    for (int i=x11[id];i<=x22[id];i++) {
        for (int j=y11[id];j<=y22[id];j++) {
            cout << a[i][j][re] << ' ';
        }
        cout << '\n';
    }*/
    for (int i=x11[id];i<=x22[id];i++) {
        for (int j=y11[id];j<=y22[id];j++) {
//            a[x22[id]-(j-y11[id])][i-x11[id]+y11[id]][re+1]=a[i][j][re];
            a[j-y11[id]+x11[id]][x22[id]-i+y11[id]][re+1]=a[i][j][re];
        }
    }
/*    for (int i=x11[id];i<=x22[id];i++) {
        for (int j=y11[id];j<=y22[id];j++) {
            cout << a[i][j][re+1] << ' ';
        }
        cout << '\n';
    }*/
}

void dfs(int id,int cost) {
    if (id==16) {
        ans=min(ans,cost);
        return;
    }
    for (int k=0;k<4;k++) {
        int flag=1;
        if (cost+k>ans) continue;
        for (int i=x11[id];i<=x22[id];i++) {
            for (int j=y11[id];j<=y22[id];j++) {
                if (r[i][a[i][j][k]]) {
                    flag=0;break;
                }
                if (c[j][a[i][j][k]]) {
                    flag=0;break;
                }
            }
        }
        if (flag) {
            for (int i=x11[id];i<=x22[id];i++) 
                for (int j=y11[id];j<=y22[id];j++) 
                    r[i][a[i][j][k]]=c[j][a[i][j][k]]=1;
            dfs(id+1,cost+k);
            for (int i=x11[id];i<=x22[id];i++) 
                for (int j=y11[id];j<=y22[id];j++) 
                    r[i][a[i][j][k]]=c[j][a[i][j][k]]=0;
        }
    }
}

int main() {
    int cas;
    scanf("%d",&cas);
    while (cas--) {
        for (int i=1;i<=16;i++) {
            scanf("%s",s[i]+1);
            for (int j=1;j<=16;j++) {
                if (s[i][j]>='A'&&s[i][j]<='Z') {
                    a[i][j][0]=s[i][j]-'A'+10;
                } else a[i][j][0]=s[i][j]-'0';
            }
        }
        for (int j=0;j<=2;j++) {
            for (int k=0;k<16;k++) 
                rotate(k,j);
        }
    /*    for (int k=0;k<4;k++){
        for (int i=1;i<=16;i++) {
            for (int j=1;j<=16;j++) {
                cout << a[i][j][k] << ' ';
                if (a[i][j][k]<=9) cout << ' '; 
            }
            cout << '\n';
        }
        cout << '\n';}*/
        ans=inf;
        mem0(r);mem0(c);
        dfs(0,0);
        assert(ans!=inf);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_35406909/article/details/81347298
今日推荐