https://www.luogu.org/problemnew/show/P1074

显然是dfs 而且没有什么剪枝记忆化之类的 但是预处理比较麻烦

我用三个二维数组存状态:visx[x][i]代表x行有没有选 i 这个数   visy[y][i]代表y列有没有选 i    visg[g][i]代表第g个九宫格有没有选i

当遍历的时候 发现visx[x][i]==0&&visy[y][i]==0&&visg[g][i]==0 说明 i 还没有被选 就可以向下dfs

至于遍历的顺序 我们玩数独的时候都知道 肯定先从已知点比较多的地方开始考虑

比如 第一行:7 0 0 9 0 0 0 0 1 有6个位置未知

第九行:0 8 0 5 0 4 0 1 2 只有4个位置未知 那么我们肯定先考虑第九行

所以只需要把行sort排序一下 调整一下遍历的顺序即可

不过排序又引申出来一个问题 就是我们不知道排序之后的第一行 原来是第几行 为了解决这个问题 我们可以用一个结构体存储每一行有几个未知位置:

typedef struct
{
int nums=; //未知位置数量
int x; //行数
}node;

最后 我们需要维护一个一维数组,用来保存修正后的遍历的序列(当然二维也可以)

最后的的最后 每找到一组数独的解 都要更新最大值

具体看代码吧:

#include<bits/stdc++.h>

using namespace std;

typedef struct
{
int nums=;
int x;
}node;
node e[]; int m[][],anss,u,visx[][],visy[][],visg[][],q[],pre,flag;
int s[][]={,,,,,,,,,,, //保存每个位置上的分数 比较懒 直接打表了
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,,
,,,,,,,,,,}; bool cmp(node a,node b)
{
return a.nums<b.nums;
} void dfs(int t)
{
int i,j;
if(t==u+)
{
flag=;
int p=;
for(i=;i<=;i++)
for(j=;j<=;j++)
p+=m[i][j]*s[i][j];
anss=max(anss,p); //更新最大值
return;
}
int x=(q[t]-)/+;
int y=q[t]-(x-)*;
int g=((x-)/)*+(y-)/+;
for(i=;i<=;i++)
{
if(visx[x][i]==&&visy[y][i]==&&visg[g][i]==)
{
visx[x][i]=;
visy[y][i]=;
visg[g][i]=;
m[x][y]=i;
dfs(t+);
visx[x][i]=;
visy[y][i]=;
visg[g][i]=;
}
}
} int main()
{
int i,j;
for(i=;i<=;i++)
e[i].x=i;
for(i=;i<=;i++)
for(j=;j<=;j++)
{
scanf("%d",&m[i][j]);
if(m[i][j]==)
e[i].nums++;
else
{
pre+=m[i][j]*s[i][j];
visx[i][m[i][j]]=;
visy[j][m[i][j]]=;
int g=((i-)/)*+(j-)/+; //计算当前点属于哪一个九宫格
visg[g][m[i][j]]=;
}
}
sort(e+,e+,cmp);
for(i=;i<=;i++)
for(j=;j<=;j++)
{
if(m[e[i].x][j]==)
{
int nums=(e[i].x-)*+j; //如果当前位置未知,把他放入准备遍历的序列里
q[++u]=nums; //u记录了有多少点未知
}
}
dfs();
if(flag==) //如果无解
{
cout<<-<<endl;
return ;
}
cout<<anss<<endl; }

P1074 靶形数独 dfs+预处理的更多相关文章

  1. P1074 靶形数独 dfs回溯法

    题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的“靶 ...

  2. P1074 靶形数独

    P1074 靶形数独正着搜80分,完全倒置95分,完全倒置后左右再倒置,就会A掉,到时候脑洞要大一些. #include<iostream> #include<cstdio> ...

  3. 洛谷——P1074 靶形数独

    P1074 靶形数独 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z ...

  4. P1074 靶形数独题解

    题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的“靶 ...

  5. 洛谷P1074 靶形数独 [搜索]

    题目传送门 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了 ...

  6. NOIP2009靶形数独[DFS 优化]

    描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z博士请教,Z 博士拿出了他最近发明的“靶形数独 ...

  7. [洛谷P1074] 靶形数独

    洛谷题目链接:靶形数独 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博 ...

  8. 洛谷 P1074 靶形数独

    题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...

  9. [NOIP2009] 提高组 洛谷P1074 靶形数独

    题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...

随机推荐

  1. 浅谈redis分布式锁用法

    使用redis的setnx命令进行实现 @Component @Slf4j public class RedisLock { @Autowired private StringRedisTemplat ...

  2. iOS 自定义NavigationBar右侧按钮rightBarButtonItem

    自定义右侧的一个按钮 UIBarButtonItem *myButton = [[UIBarButtonItem alloc] initWithTitle:@"主页" style: ...

  3. tensorflow 中 name_scope和variable_scope

    import tensorflow as tf with tf.name_scope("hello") as name_scope: arr1 = tf.get_variable( ...

  4. 两台linux服务器相互拷贝文件的两个方法

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  5. Error: pgraster_wkb_reader: grayscale band type 10 unsupported

    错误原因:Float32 is not supported for rendering.即栅格数据类型Float32不支持. cmd中用GDAL查看.在波段中的数据类型是Float32的不支持渲染. ...

  6. The Preliminary Contest for ICPC Asia Shanghai 2019 J. Stone game

    题目:https://nanti.jisuanke.com/t/41420 思路:当a(a∈S′)为最小值 如果Sum(S′)−a≤Sum(S−S′)成立 那么(∀t∈S′,Sum(S′)−t≤Sum ...

  7. ICPC — International Collegiate Programming Contest Asia Regional Contest, Yokohama, 2018–12–09 题解

    目录 注意!!此题解存在大量假算法,请各位巨佬明辨! Problem A Digits Are Not Just Characters 题面 题意 思路 代码 Problem B Arithmetic ...

  8. SWPU2019 伟大的侦探

    01editor 选择 EBCDIC编码得到压缩包的密码 这里用到的是福尔摩斯里面的跳舞的小人加密 结果是:iloveholmesandwllm

  9. 使用FunctionalInterface提供工厂方法

    1. 首先提供User类 public class User { private int id; private String name; public User(int id, String nam ...

  10. libusb获取usb设备的idVendor(vid),idProduct(pid),以及Serial Number

    发表于2015/6/23 21:55:11  4594人阅读 最近在做关于usb设备的项目,用到了libusb,发现关于这个的函数库的介绍,讲解很少,下面仅仅是简单展示一些基本的使用方法,以备后用. ...