题目传送

主要是搜索顺序不同导致效率千差万别。

联想人做数独的策略,总是先填可填数最少的那个空,再填选择第二少的。。。其实这种策略就造就了一个深度浅时分支也较少的搜索树。合适的搜索顺序再配合剪枝==AC。

所以搜索顺序为:从当前可填数的数目最少的那个空开始。注意:每填一个空,都会导致同行同列同九宫格的空的可填数数目减一,所以不能一开始就排序。(实测这样做会比正解慢8倍左右,真是恐怖如斯)所以要在分支选择时去找。为了平衡准确性与高效性,可以用一个简单的判断找到一个比较合适的空去填(因为如果每次都精确去找那个可填数数目最小的那个空会导致复杂度偏高,因此只要简单地找到可填数数目相对小的那个空就行)。

找一下搜索面临或有关的状态与维度:当前分数v,当前要填的点的坐标,填了t个点,总共要填cnt个点,各行各列各九宫格填数情况。

可行性剪枝考虑:

  发现一个有趣的性质:数独中每一行都会有1到9各出现一次,共有9行,所以1到9每个数到最后必定出现9次,所以可以设一个used[]数组记录数出现的次数,若小于0,肯定不是正解,回溯,故每次填空要用不仅usedi大于0且i在同行同列同九宫格都没有出现过的i。

最优性剪枝:

  可以将所有空能填的最大的数*该空的分数求和得到一个还能得到的至多的分数zhiduo,填空时,若发现v+zhiduo还<=已搜到的答案ans,显然不会使答案更优,所以回溯;同时每填一个空都更新一下zhiduo,回溯时也要照顾到zhiduo。

AC代码:

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm> using namespace std; int a[][],fen[][],cnt,zhiduo,m[][],ans;//第二下标: 0:纵坐标;1:横坐标 先纵再横
int ma[][],used[];
int h[],l[],maxh,maxl;//某行、列已经填了几个数 bool hang[][],lie[][],jiu[][][];//行、列、九宫格的填数情况 void init()
{
for(int i=;i<=;i++) used[i]=;
for(int f=;f<=;f++)//初始化每个空的分数,不懂的可以拿纸笔自己模拟一下
{
for(int i=f-;i<=-f+;i++) fen[f-][i]=fen[-f+][i]=f;
for(int j=f-+;j<=-f+-;j++) fen[j][f-]=fen[j][-f+]=f;
}
} void dfs(int k,int v,int x,int y)//要填第k个,当前分数v,当前填的空的纵、横坐标。
{
if(v+zhiduo<=ans) return;//最优性剪枝
for(int i=;i<=;i++)//填哪个数
{
if(used[i]&&(!hang[x][i])&&(!lie[y][i])&&(!jiu[x/][y/][i]))//可行性剪枝
{
v+=fen[x][y]*i;
if(k!=cnt)
{
used[i]--;
hang[x][i]=;lie[y][i]=;jiu[x/][y/][i]=;
h[x]++;l[y]++;
zhiduo-=fen[x][y]*ma[x][y];
maxh=maxl=;
a[x][y]=i;
for(int i=;i<=;i++) if(h[i]!=&&h[i]>h[maxh]) maxh=i;//找接下来要填的空
for(int i=;i<=;i++) if(!a[maxh][i]&&l[i]!=&&l[i]>l[maxl]) maxl=i;
dfs(k+,v,maxh,maxl);
hang[x][i]=;lie[y][i]=;jiu[x/][y/][i]=;//回溯的时候少一个都会wa啊
zhiduo+=fen[x][y]*ma[x][y];
h[x]--;l[y]--;
a[x][y]=;
used[i]++;
}
else
ans=max(ans,v);
v-=fen[x][y]*i;
}
}
} int main()
{
init();
int v=;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j])
{
used[a[i][j]]--;
h[i]++;
l[j]++;
if(hang[i][a[i][j]]||lie[j][a[i][j]]||jiu[i/][j/][a[i][j]])
{
cout<<-;
return ;
}
hang[i][a[i][j]]=;
lie[j][a[i][j]]=;
jiu[i/][j/][a[i][j]]=;
v+=fen[i][j]*a[i][j];
}
else
cnt++;
}
int most;
for(int i=;i<=;i++)//求起始时的至多zhiduo
for(int j=;j<=;j++)
if(!a[i][j])
{
most=;
while(hang[i][most]||lie[j][most]||jiu[i/][j/][most]) most--;
ma[i][j]=most;//空(j,i)能填的最大的数
zhiduo+=most*fen[i][j];
}
h[]=-;
l[]=-;
maxh=,maxl=;
for(int i=;i<=;i++)//找一开始要填的空
if(h[i]!=&&h[i]>h[maxh]) maxh=i;
for(int i=;i<=;i++)
if(!a[maxh][i]&&l[i]!=&&l[i]>l[maxl]) maxl=i;
dfs(,v,maxh,maxl);
if(!ans) ans=-;
cout<<ans;
return ;
}

一本通&&洛谷 ——靶型数独——题解的更多相关文章

  1. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  2. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  3. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  4. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

  5. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  6. 洛谷 P1220 关路灯 题解

    Description 有 $n$ 盏路灯,每盏路灯有坐标(单位 $m$)和功率(单位 $J$).从第 $c$ 盏路灯开始,可以向左或向右关闭路灯.速度是 $1m/s$.求所有路灯的最少耗电.输入保证 ...

  7. 【洛谷P3410】拍照题解(最大权闭合子图总结)

    题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. 注意:带下属不是白带的 ...

  8. [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)

    [BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...

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

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

随机推荐

  1. 不容错过的 MySQL史上最全

    点击下方链接 http://c.biancheng.net/view/2361.html

  2. js 中 json.stringfy()将对象、数组转换成字符串

    json.stringfy()将对象.数组转换成字符串 var student = new Object(); student.name = "Lanny"; student.ag ...

  3. tensorflow学习笔记六----------神经网络

    使用mnist数据集进行神经网络的构建 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from ...

  4. P2220 [HAOI2012]容易题

    传送门 首先 $(\sum_{i=1}^{n}a_i)(\sum_{i=1}^{m}b_i)$ 展开以后包含了所有 $ab$ 两两相乘的情况并且每种组合只出现一次 发现展开后刚好和题目对序列价值的定义 ...

  5. 【转】MySQL my.cnf 参数 详解

    [client] port    = 3306    //客户端端口号为3306 socket  = /tmp/mysql.sock  //套接字文件(sockets),这种文件一般用在网络上的资料套 ...

  6. Centos克隆虚拟机后配置网络

    修改网卡相关信息,复制第二个网卡的mac地址. vim /etc/udev/rules.d/70-persistent-net.rules 修改网卡的信息 vim /etc/sysconfig/net ...

  7. MySQL索引面试题分析(索引分析,典型题目案例)

    [建表语句] create table test03( id int primary key not null auto_increment, c1 char(10), c2 char(10), c3 ...

  8. elasticsearch——Rest Client

    https://www.jianshu.com/p/66b91bec12e3 elasticsearch——Rest Client 0.2372018.05.10 15:23:03字数 1287阅读 ...

  9. Linux系统安装使用实录--传送门(持续更新)

    1.安装Linux系统 经过两种系统对比,发现ubuntu的资源依赖更方便更全,  centos安装时可以配置开发环境,默认有安装的jdk,这一点比Ubuntu方便一点. win10+centos  ...

  10. tp5 模板参数配置(模板静态文件路径)

    tp5 模板参数配置(模板静态文件路径) // 模板页面使用 <link rel="stylesheet" type="text/css" href=&q ...