一本通&&洛谷 ——靶型数独——题解




主要是搜索顺序不同导致效率千差万别。
联想人做数独的策略,总是先填可填数最少的那个空,再填选择第二少的。。。其实这种策略就造就了一个深度浅时分支也较少的搜索树。合适的搜索顺序再配合剪枝==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 ;
}
一本通&&洛谷 ——靶型数独——题解的更多相关文章
- 洛谷P2832 行路难 分析+题解代码【玄学最短路】
洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...
- 【洛谷P3960】列队题解
[洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...
- 洛谷P2312 解方程题解
洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...
- 洛谷P1577 切绳子题解
洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷 P1220 关路灯 题解
Description 有 $n$ 盏路灯,每盏路灯有坐标(单位 $m$)和功率(单位 $J$).从第 $c$ 盏路灯开始,可以向左或向右关闭路灯.速度是 $1m/s$.求所有路灯的最少耗电.输入保证 ...
- 【洛谷P3410】拍照题解(最大权闭合子图总结)
题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. 注意:带下属不是白带的 ...
- [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)
[BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...
- 洛谷P1074 靶形数独 [搜索]
题目传送门 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了 ...
随机推荐
- 卷积神经网络应用于MNIST数据集分类
先贴代码 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist = inpu ...
- Pyinstaller-封装python
1. 当程序中没有调用matplotlib模块 ① pip intall pyinstaller ② 在cmd环境下,pyinstaller -F xxx.py 2.当程序中调用matplotlib ...
- Mongodb-简单部署
一.MongoDB是一款NoSql数据库 二.部署单实例MongoDB 1.安装环境: (1)系统:Centos7.2 (2)MongoDB:Percona的MongoDB3.4 2.配置yum源 p ...
- RabbitMQ 安装步骤
RabbitMQ安装步骤 一.安装erlang 1.下载erlang wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1 ...
- cqoj921E整数匹配
这是一个贪心题,把我坑的好惨,忘还原得70.上午被卡得,, 首先给出长度为n的一组数,可以两两配对相乘也可以进行相加,问怎样才可以使总和最大?那么可以显然看出来,当这个数为0或1时,我们要相加.其余进 ...
- QT DBUS: Not connected to D-Bus server, 注意source /etc/profile
运行环境:ARM 运行如下代码: QDBusConnection bus = QDBusConnection::sessionBus(); if(!bus.registerService(" ...
- 卷积神经网络(ConvNets)中卷积的实现
#include <iostream> #include <sstream> #include <fstream> #include <algorithm&g ...
- 并发编程时守护进程在pycharm与python shell中的运行结果不同
原代码如下 from multiprocessing import Process import time import random def task(name): print('%s is run ...
- Vue.nextTick浅析
Vue.nextTick浅析 Vue的特点之一就是响应式,但数据更新时,DOM并不会立即更新.当我们有一个业务场景,需要在DOM更新之后再执行一段代码时,可以借助nextTick实现.以下是来自官方文 ...
- linux:shell脚本格式
shell脚本格式: #!/bin/bash //第一行指定bash 命令群..... 例子: #!/bin/bash DESCDIR='/tmp/t ...