hdu6341 Problem J. Let Sudoku Rotate (dfs)
题目传送门
题意:
给你16个16宫格的数独,里面是0~F,你可以逆时针旋转里面的每个16宫格
问你它是从标准数独逆时针旋转多少次得到?
思路:
可以知道每个16宫已经是标准的了,接下来只要考虑每行、每列就行了
那么我们在dfs中就可以用两个行列两个数组来标记每个数字出现的次数,
大于1则不行
另外此时是逆时针来的,那么你就要顺时针回去
逆一次等于顺3次
参考博客:https://www.cnblogs.com/zquzjx/p/10326048.html
代码:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 25
int g[N][N],G[N][N];
int R[N][N],C[N][N];
int ans; int get(int x,int y,int I,int J,int k)
{
if(k==) return g[y+-J+][x+I];
else if(k==) return g[x+-I+][y+-J+];
else if(k==) return g[x][y+-I+];
else return g[x+I][y+J];
}
bool Rotate(int x,int y,int k)
{
bool flag=;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
int xx=(x-)*+i;
int yy=(y-)*+j;
G[xx][yy]=get(xx,yy,i,j,k);//cout<<xx<<" "<<yy<<" "<<G[xx][yy]<<endl;
// cout<<(x-1)*4+i<<" "<<(y-1)*4+j<<endl;
int r=++R[xx][G[xx][yy]];
int l=++C[yy][G[xx][yy]];
if(r>||l>) flag=;
}
}
return flag;
}
void reRotate(int x,int y)
{
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
int xx=(x-)*+i;
int yy=(y-)*+j;
--R[xx][G[xx][yy]];
--C[yy][G[xx][yy]];
G[xx][yy]=g[xx][yy];
}
}
}
void dfs(int x,int y,int sum)
{
if(x==)
{
ans=min(ans,sum);
return ;
}
for(int i=;i<=;i++)
{
if(!Rotate(x,y,i))
{
reRotate(x,y);
continue;
}
if(y==) dfs(x+,,sum+i);
else dfs(x,y+,sum+i);
reRotate(x,y);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
char s[];
for(int i=;i<=;i++)
{
scanf("%s",s+);
for(int j=;j<=;j++)
{
if(s[j]>=''&&s[j]<='') g[i][j]=s[j]-''+;
else g[i][j]=s[j]-'A'+;
}
}
/*for(int i=1;i<=16;i++){
for(int j=1;j<=16;j++)
printf("%d",g[i][j]);
cout<<endl;}*/
memset(R,,sizeof(R));
memset(C,,sizeof(C));
ans=INF;
dfs(,,);
printf("%d\n",ans);
}
return ;
}
参考代码:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define mem(i,j) memset(i,j,sizeof(i))
const int N=1e5+;
const int MOD=1e9+; int G[][], g[][];
int R[][], C[][];
int ans; #define w(i) (i-1)*4
#define wG(i,j,I,J) G[w(i)+I][w(j)+J]
int get(int r,int c,int x,int y,int k) {
if(k==) return wG(r,c,-y+,x);
else if(k==) return wG(r,c,-x+,-y+);
else if(k==) return wG(r,c,y,-x+);
else return wG(r,c,x,y);
}
// 得到在r,c的块内x,y位置在第k种旋转之后的新数值 bool Rotate(int i,int j,int k) {
bool OK=;
for(int I=;I<=;I++)
for(int J=;J<=;J++) {
int x=w(i)+I, y=w(j)+J;
g[x][y]=get(i,j,I,J,k);
int r=++R[x][g[x][y]];
int c=++C[y][g[x][y]];
if(r> || c>) OK=;
// 这种旋转与之前其他块的旋转冲突
// 继续发展下去得到的一定是错误的
}
return OK;
} // 旋转i,j块 方式为第k种
void reRotate(int i,int j) {
for(int I=;I<=;I++)
for(int J=;J<=;J++) {
int x=w(i)+I, y=w(j)+J;
--R[x][g[x][y]];
--C[y][g[x][y]];
g[x][y]=G[x][y];
}
} // 将i,j块的旋转取消 void dfs(int x,int y,int sum) {
if(sum>ans) return;
if(x==) {
ans=min(ans,sum);
return;
} // 四行四列16个块 到第五行说明已枚举了所有块的旋转 for(int i=;i<=;i++) {
if(Rotate(x,y,i)==) {
reRotate(x,y); continue;
} // 若发现这种旋转方式会冲突就跳过
if(y==) dfs(x+,,sum+i);
else dfs(x,y+,sum+i);
reRotate(x,y);
}
} // 搜索枚举16个块的旋转方式 int main()
{
int t; scanf("%d",&t);
while(t--) {
for(int i=;i<=;i++) {
char s[]; scanf("%s",s);
for(int j=;j<;j++) {
if(s[j]>='' && s[j]<='')
G[i][j+]=s[j]-'';
else G[i][j+]=s[j]-'A'+;
}
} mem(R,); mem(C,);
ans=INF; dfs(,,);
printf("%d\n",ans);
} return ;
}
hdu6341 Problem J. Let Sudoku Rotate (dfs)的更多相关文章
- HDU-6341 Problem J. Let Sudoku Rotate(dfs 剪枝)
题目:有一个4*4*4*4的数独,每一横每一竖每一个小方块中都无重复的字母,即都为0-9,A-F..有一个已经填好的数独,若干个4*4的方块被逆时针拧转了若干次,问拧转回来至少需要多少次. 分析:很明 ...
- 2018 Multi-University Training Contest 4 Problem J. Let Sudoku Rotate 【DFS+剪枝+矩阵旋转】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6341 Problem J. Let Sudoku Rotate Time Limit: 2000/100 ...
- HDU - 6341 多校4 Let Sudoku Rotate(状压dfs)
Problem J. Let Sudoku Rotate Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K ...
- hdu第4场j.Let Sudoku Rotate
Problem J. Let Sudoku Rotate Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Su ...
- 深度优先搜索(dfs)与出题感想
在3月23号的广度优先搜索(bfs)博客里,我有提到写一篇深搜博客,今天来把这个坑填上. 第一部分:深度优先搜索(dfs) 以上来自百度百科. 简单来说,深度优先搜索算法就是——穷举法,即枚举所有情况 ...
- LeetCode Subsets (DFS)
题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. class Sol ...
- 深搜(DFS)广搜(BFS)详解
图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...
- 【算法导论】图的深度优先搜索遍历(DFS)
关于图的存储在上一篇文章中已经讲述,在这里不在赘述.下面我们介绍图的深度优先搜索遍历(DFS). 深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj:访问vj之后,又访问vj的一个邻接点, ...
- 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现
1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...
随机推荐
- passwd - 密码文件
描述 Passwd 是个文本文件, 它包含了一个系统帐户列表, 给出每个帐户一些有用的信息,比如用户 ID,组 ID, 家目录, shell,等. 通常它也包含了每个用户经过加密的密码. 它通常应该是 ...
- 14DBCP连接池
实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection.这样我们就不需要每次都创建连接.释放连接了,这些操作 ...
- scapy - 基于python的数据包操作库
简介 地址:https://github.com/secdev/scapy scapy是一个基于python的交互式数据包操作程序和库. 它能够伪造或者解码多种协议的数据包,通过使用pcap文件对他们 ...
- Android解决冲突
1.在app的build.gradle中的defaultConfig节点中配置configurations.all android{ ... defaultConfig { configuration ...
- json和dict 在requests中请求
上面的问题,在这么晚的夜里解决了 data 接受的是json格式数据, json 接受dict格式点的数据, 这个文章中也讲到了https://www.cnblogs.com/beile/p/1086 ...
- 碎片记录——JMeter之 http post json对象与参数化调用,以及beanshell 引用Java源码
参考文档 http://jmeter.apache.org/usermanual/component_reference.html#samplers https://blog.csdn.net/qq_ ...
- tensorboard可视化(先写一点点)
在tensorboard上显示运行图: import tensorflow as tf a = tf.constant(10,name="a") b = tf.constant(9 ...
- python-Exception异常使用
Exception #自定义异常类 ,MyInputExcp继承Exception异常 class MyInputExcp(Exception): def __init__(self, lenght, ...
- ng mvc + @Valid + @RequestBody 接收json同时校验javaBean的数据有效性
@Valid @RequestBody CustomerDto customerBean @RequestMapping(value="/customerDataSync.do", ...
- [CSP-S模拟测试]:数字(数学+高精度)
题目描述 很简单,给出正整数$n$,求出$n!$在十进制表示下的从最末非零位开始的总共$k$位. 输入格式 第一行一个正整数$T$,表示有$T$组数据接下来$T$行,每行两个正整数$n$和$k$. 输 ...