题目

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

靶形数独的方格同普通数独一样,在 99 格宽×99 格高的大九宫格中有9 9 个 33 格宽×33 格高的小九宫格(用粗黑色线隔开的)。在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入 11 到 9 9的数字。每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。但靶形数独有一点和普通数独不同,即每一个方格都有一个分值,而且如同一个靶子一样,离中心越近则分值越高。(如图)

上图具体的分值分布是:最里面一格(黄色区域)为 1010 分,黄色区域外面的一圈(红色区域)每个格子为 9 9分,再外面一圈(蓝色区域)每个格子为 88 分,蓝色区域外面一圈(棕色区域)每个格子为 7 7分,最外面一圈(白色区域)每个格子为 6 6分,如上图所示。比赛的要求是:每个人必须完成一个给定的数独(每个给定数独可能有不同的填法),而且要争取更高的总分数。而这个总分数即每个方格上的分值和完成这个数独时填在相应格上的数字的乘积的总和

总分数即每个方格上的分值和完成这个数独时填在相应格上的数字的乘积的总和。如图,在以下的这个已经填完数字的靶形数独游戏中,总分数为 2829。游戏规定,将以总分数的高低决出胜负。

由于求胜心切,小城找到了善于编程的你,让你帮他求出,对于给定的靶形数独,能够得到的最高分数。

题目大意

在9*9的矩阵内,每一个点都有一个分数,你先在需要求出一个数独使得数独上的每一个点乘这个点的分数之和最大,并输出这一个分数。

做法

这一道题目的难点就是求解数独的过程,我们需要对整一个搜索树进行剪枝。

如果我们需要对整一个问题的时间复杂度进行优化,我们需要:

  • 在每一次搜索的时候不以点的顺序进行搜索,而是找到可以选择点数最小的格子进行搜索,这样整一棵搜索树的的规模就变小了;因此搜索的参数就是剩下的点数而不是当前的坐标,然后我们暴力找到可以选出的最小点(常数 = 81 可以忽略)。

然后就需要进行常数优化惹:

  • 显然每一个状态如果用数组标记和调用都过于浪费时间,我们可以用27个9位二进制数来分别标记行、列和九宫格的状态。如果需要找到当前可以用的数字,可以使用lowbit运算(返回末尾连续的0和第一个1的数值),然后需处理一下即可知道数字,暴力标记即可。

现在回到找最小点这一个问题上:

  • 我们可以枚举每一个点,通过二进制,得到对应的1的位置;而每一个二进制数有多少个1则需要通过预处理解决,在一个数的基础上不断减lowbit即可;而每一个位置可以填的条件就是行、列、九宫格做与运算的结果,如果当前值是0说明不合法直接退出即可。
#include <bits/stdc++.h>
using namespace std;
bool flag;
int x[200];
int y[200];
int n[200];
int tot[300];
int num[1000000];
char s[300][300];
int nine[100][100]=
{{0,0,0,0,0,0,0,0,0,0},{0,1,1,1,2,2,2,3,3,3},{0,1,1,1,2,2,2,3,3,3},{0,1,1,1,2,2,2,3,3,3},{0,4,4,4,5,5,5,6,6,6},{0,4,4,4,5,5,5,6,6,6},{0,4,4,4,5,5,5,6,6,6},{0,7,7,7,8,8,8,9,9,9},{0,7,7,7,8,8,8,9,9,9},{0,7,7,7,8,8,8,9,9,9}
};
void print(void)
{for (int i=1;i<=9;++i){for (int j=1;j<=9;++j)cout<<s[i][j];}puts("");
}
void change(int i,int j,int v)
{x[i]^=(1<<v-1);y[j]^=(1<<v-1);n[nine[i][j]]^=(1<<v-1);
}
bool dfs(int D)
{if (D==0) return 1;int Min=INT_MAX,xx=0,yy=0,temp;for (int i=1;i<=9;++i)for (int j=1;j<=9;++j)if (s[i][j]=='.'){int now=x[i]&y[j]&n[nine[i][j]];if (now==0) return 0;if (tot[now]<Min){Min=tot[now];xx=i;yy=j;temp=now;}}for (int i=temp;i;i-=(i&-i)){int low=i&-i;int k=num[low];change(xx,yy,k);s[xx][yy]=k+'0';if (dfs(D-1)) return 1;change(xx,yy,k);s[xx][yy]='.';}return 0;
}
int main(void)
{freopen("b.in","r",stdin);freopen("b.out","w",stdout);for (int i=0;i<(1<<10);++i)for (int j=i;j;j-=(j&-j))tot[i]++;for (int i=1;i<10;++i) num[1<<i-1]=i; //累计每一个数lowbit值中的1的个数 cin>>s[1][1];up:flag=0;for (int i=1;i<=9;++i)for (int j=(i==1?2:1);j<=9;++j)cin>>s[i][j];for (int i=1;i<=9;++i)x[i]=y[i]=n[i]=(1<<9)-1;//初始化:将每一个二进制位改成全1 int sum=0;for (int i=1;i<=9;++i)for (int j=1;j<=9;++j)if (s[i][j]!='.'){int v=s[i][j]-'0';change(i,j,v);}else sum++;dfs(sum);print();cin>>s[1][1];if (s[1][1]!='e') goto up;return 0;
}

【习题·搜索】[NOIP2009]靶型数独(搜索+剪枝+位运算优化)相关推荐

  1. 数独 dfs 剪枝 位运算 保姆注释版 java

  2. 有趣的题目:简单深搜之数独与靶型数独--二进制状压加速与dfs数独剪枝

    Sudoku Time Limit: 2000MS   Memory Limit: 65536K 题目链接http://poj.org/problem?id=2676 Description Sudo ...

  3. 【NOIP2009】【DLX】【位运算】T4 靶形数独 题解

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

  4. [luogu p1074] 靶型数独

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

  5. 【NOIP2019提高组第四题】靶型数独

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

  6. 位运算与组合搜索(二)

    People who play with bits should expect to get bitten. -- Jurg Nievergelt I failed math twice, never ...

  7. ElasticSearch搜索实例含高亮显示及搜索的特殊字符过滤

    应用说明见代码注解. 1.简单搜索实例展示: public void search() throws IOException {// 自定义集群结点名称String clusterName = &qu ...

  8. 【飞秋】位运算与组合搜索(二)

    这篇文章接着讲怎样高效地遍历所有的组合.同样,假定全集的大小不大于机器字长,计算模型为 word-RAM,即诸如 +, –, *, /, %, &, |, >>, << ...

  9. 转:MSDN Visual系列:MOSS企业级搜索之一——在搜索中心里创建自定义搜索页面和标签选项卡...

    MSDN Visual系列:MOSS企业级搜索之一--在搜索中心里创建自定义搜索页面和标签选项卡 原文:http://msdn2.microsoft.com/en-us/library/bb42885 ...

最新文章

  1. 人与机器——解析人工智能的三大类别以及哲学家的相关思想实验
  2. Windows 10 to Go
  3. copying mysql status_mysql慢查询copying to tmp table
  4. java基础—Date类的常见方法演示
  5. eclipse - 自动换行
  6. UI设计灵感|迷人的概念加载动画设计
  7. x86-64函数调用参数传递
  8. STM32开发环境搭建
  9. JSON转换问题最全详解(json转List,json转对象,json转JSONObject)
  10. mysql性能调优面试题_面试题大全-mysql性能优化方案
  11. matlab 打不开 slx,matlab2014a打不开仿真参数设置对话框怎么办
  12. 日期格式化在高并发场景下的解决方案
  13. Android开发——网络请求(一)网络请求的API、授权和方法
  14. [PTA]实验3-4 统计字符
  15. Word中公式变量解释时破折号对齐方法
  16. CSS学习笔记(学习中)
  17. 小程序如何在其他页面监听globalData中值的变化?
  18. 哈工大计算机研究生院著名导师,哈尔滨工业大学研究生导师介绍:李海峰-中公研招网...
  19. SpringBoot: Could not resolve placeholder 'XXXX' in value ${XXXX}
  20. WordPress常见问题及其解决方法

热门文章

  1. 2021年安全员-B证考试总结及安全员-B证试题及解析
  2. 主流数据恢复软件——EasyRecovery/Ashampoo Undeleter/Wise Data Recovery/Recuva/Undelete 360
  3. 基于RFID的仓储管理系统——实习报告
  4. 圆通快递回应内鬼泄露用户信息:严打数据倒卖灰色产业
  5. ruoyi 多模块部署_ruoyi-cloud版本新建模块
  6. ​DCIC 2020:智慧海洋建设 开源方案复盘笔记
  7. 转载自---课内实验记录|信用卡号的合法性检查 2019年05月05日 21:37:45 @退堂鼓一级演员
  8. 13-07-支付场景
  9. 2020年十大IC设计企业
  10. 一淘公布假报告让电商行业再临诚信考验