hdu6341 Problem J. Let Sudoku Rotate
Problem J. Let Sudoku Rotate
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
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
1
681D5A0C9FDBB2F7
0A734B62E167D9E5
5C9B73EF3C208410
F24ED18948A5CA63
39FAED5616400B74
D120C4B7CA3DEF38
7EC829A085BE6D51
B56438F129F79C2A
5C7FBC4E3D08719F
AE8B1673BF42A58D
60D3AF25619C30BE
294190D8EA57264C
C7D1B35606835EAB
AF52A1E019BE4306
8B36DC78D425F7C9
E409492FC7FA18D2
Sample Output
5
Hint
The original sudoku is same as the example in the statement.
Source
2018 Multi-University Training Contest 4
Recommend
chendu | We have carefully selected several similar problems for you: 6343 6342 6341 6340 6339
Solution
转载:https://blog.csdn.net/ACM2017/article/details/81350991
每一个4*4小格子都可以判断一下是否还需旋转九十度:若是此小格子与它前面的每行都不冲突,与它前面的每一列都不冲突,则这个小格子不需要旋转九十度。
得多练搜索啊,差点做成枚举,一直往后搜,加上剪枝
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
char str[20][20],tmp[20][20];
int ans;
int vis[20];
int tot;
void rot(int x,int y)
{
for(int i = x;i < x + 4;++i)
{
for(int j = y;j < y + 4;++j)
{
tmp[x + j % 4][y + 3 - i % 4] = str[i][j];
}
}
for(int i = x;i < x + 4;++i)
{
for(int j = y;j < y + 4;++j)
{
str[i][j] = tmp[i][j];
}
}
}
bool judge(int a,int b)
{
int tot = 0;
memset(vis,0,sizeof(vis));
//利用一个vis数组来判定有没有重复出现
for(int i = a;i < a + 4;++i)
{
tot++;
for(int j = 0;j < b + 4;++j)
{
if(vis[str[i][j]] == tot)
return 0;
vis[str[i][j]] = tot;
}
}
for(int i = b;i < b + 4;++i)
{
tot++;
for(int j = 0;j < a + 4;++j)
{
if(vis[str[j][i]] == tot)
return 0;
vis[str[j][i]] = tot;
}
}
return 1;
}
void dfs(int x,int y,int sum)
{
//printf("%d %d %d\n",x,y,sum);
if(sum >= ans)
return ;
if(x == 4){
ans = min(ans,sum);
return ;
}
if(y == 4){
dfs(x + 1,0,sum);
return ;
}
for(int i = 0;i < 4;++i)
{
// printf("1\n");
// printf("%d\n",judge(4 * x,4 * y));
if(judge(4 * x,4 * y))
dfs(x,y + 1,sum + i);
rot(4 * x,4 * y);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i = 0;i < 16;++i)
{
scanf("%s",str[i]);
}
//将字母的ASCII码变成所要求的整数,可以直接转换,比较方便
for(int i = 0;i < 16;++i)
{
for(int j = 0;j < 16;++j)
{
if(isdigit(str[i][j])){
str[i][j] -= 48;
}
else{
str[i][j] -= 55;
}
}
}
ans = inf;
dfs(0,0,0);
printf("%d\n",ans);
}
return 0;
}
/*
681D5A0C43E9B2F7
0A734B628C1FD9E5
5C9B73EFA26D8410
F24ED189507BCA63
39FAED5628C10B74
D120C4B795A6EF38
7EC829A0FB346D51
B56438F17ED09C2A
26A5BC4E3D08719F
90EC1673BF42A58D
4D87AF25619C30BE
13BF90D8EA57264C
C7D1F29406835EAB
AF5287CD19BE4306
8B360E1AD425F7C9
E409653BC7FA18D2
*/
推荐阅读
-
HDU 6341 Problem J. Let Sudoku Rotate
-
HDU6341 Problem J. Let Sudoku Rotate
-
HDU 6341 Let Sudoku Rotate (DFS)
-
Hdu 6341 Problem J. Let Sudoku Rotate 暴力dfs+剪枝
-
【HDU-6341】 Let Sudoku Rotate【DFS + 剪枝】
-
HDU 6341 Let Sudoku Rotate(搜索)
-
HDU-6341:Problem J. Let Sudoku Rotate(DFS)
-
hdu 多校赛 Problem J. Let Sudoku Rotate
-
hdu6341 Problem J. Let Sudoku Rotate
-
hdu 6341 Problem J. Let Sudoku Rotate