标签:panel def BMI mem integer image des get height
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6341
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1363 Accepted Submission(s): 717
有一个 16×16 的已经打乱的数独,4×4为一宫,每次可对宫顺时针旋转 90 度。最少要操作多少次可以还原数独。
递归每一宫的左上角坐标 (x, y) ,DFS枚举每一宫的旋转次数,可知这样暴力的方案数为 4^(16) = 4294967296,需要剪枝。
由于数独的特殊性,我们枚举下一个状态前可以先判断上一个状态是否满足条件,即每行每列的数都要单独存在。
对于矩阵旋转的操作,找一下下标的规律:第一行变成第一列,第二行变成第二列,第三行变成第三列.....
AC code:
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<vector> 6 #include<queue> 7 #include<cmath> 8 #include<set> 9 #define INF 0x3f3f3f3f 10 #define LL long long 11 using namespace std; 12 const int MAXN = 20; 13 char str[MAXN][MAXN]; 14 int mmp[MAXN][MAXN]; 15 int tmp[MAXN][MAXN]; 16 bool vis[MAXN]; 17 int ans; 18 19 void rt(int x, int y) 20 { 21 int rx = 4*x, ry = 4*y-3; 22 for(int i = 4*x-3; i <= 4*x; i++){ 23 rx = 4*x; 24 for(int k = 4*y-3; k <= 4*y; k++){ 25 tmp[i][k] = mmp[rx][ry]; 26 rx--; 27 } 28 ry++; 29 } 30 31 for(int i = 4*x-3; i <= 4*x; i++){ 32 for(int j = 4*y-3; j <= 4*y; j++){ 33 mmp[i][j] = tmp[i][j]; 34 } 35 } 36 37 } 38 39 bool check(int x, int y) 40 { 41 for(int i = 4*x-3; i <= 4*x; i++){ 42 memset(vis, 0, sizeof(vis)); 43 for(int j = 1; j <= 4*y; j++){ 44 if(vis[mmp[i][j]]){ 45 return false; 46 } 47 vis[mmp[i][j]] = true; 48 } 49 } 50 for(int i = 4*y-3; i <= 4*y; i++){ 51 memset(vis, 0, sizeof(vis)); 52 for(int j = 1; j <= 4*x; j++){ 53 if(vis[mmp[j][i]]){ 54 return false; 55 } 56 vis[mmp[j][i]] = true; 57 } 58 } 59 return true; 60 } 61 62 void dfs(int x, int y, int cnt) 63 { 64 if(x > 4){ 65 ans = min(ans, cnt); 66 return; 67 } 68 for(int i = 0; i < 4; i++){ 69 if(i) rt(x, y); 70 if(check(x, y)){ 71 if(y < 4) dfs(x, y+1, cnt+i); 72 else dfs(x+1, 1, cnt+i); 73 } 74 } 75 rt(x, y); 76 } 77 78 int main() 79 { 80 int T_case; 81 scanf("%d", &T_case); 82 while(T_case--){ 83 for(int i = 0; i < 16; i++){ 84 scanf("%s", str[i]); 85 } 86 for(int i = 0; i < 16; i++){ 87 for(int j = 0; j < 16; j++){ 88 if(str[i][j] >= ‘0‘ && str[i][j] <= ‘9‘){ 89 mmp[i+1][j+1] = str[i][j]-‘0‘; 90 } 91 else mmp[i+1][j+1] = str[i][j]-‘A‘+10; 92 } 93 } 94 ans = INF; 95 dfs(1, 1, 0); 96 printf("%d\n", ans); 97 } 98 return 0; 99 }
2018 Multi-University Training Contest 4 Problem J. Let Sudoku Rotate 【DFS+剪枝+矩阵旋转】
标签:panel def BMI mem integer image des get height
原文地址:https://www.cnblogs.com/ymzjj/p/10342213.html