NOIP 2009 靶形数独(DLX)
小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低。但普通的数独对他们来说都过于简单了,于是他们向Z 博士请教,Z 博士拿出了他最近发明的“靶形数独”,作为这两个孩子比试的题目。
靶形数独的方格同普通数独一样,在 9 格宽×9 格高的大九宫格中有9 个3 格宽×3 格高的小九宫格(用粗黑色线隔开的)。在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入1 到9 的数字。每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。但靶形数独有一点和普通数独不同,即每一个方格都有一个分值,而且如同一个靶子一样,离中心越近则分值越高。(如图)
上图具体的分值分布是:最里面一格(黄色区域)为 10 分,黄色区域外面的一圈(红色区域)每个格子为9 分,再外面一圈(蓝色区域)每个格子为8 分,蓝色区域外面一圈(棕色区域)每个格子为7 分,最外面一圈(白色区域)每个格子为6 分,如上图所示。比赛的要求是:每个人必须完成一个给定的数独(每个给定数独可能有不同的填法),而且要争取更高的总分数。而这个总分数即每个方格上的分值和完成这个数独时填在相应格上的数字的乘积的总和。如图,在以下的这个已经填完数字的靶形数独游戏中,总分数为2829。游戏规定,将以总分数的高低决出胜负。
由于求胜心切,小城找到了善于编程的你,让你帮他求出,对于给定的靶形数独,能够得到的最高分数。
刚学了DLX闲着没事去试了一下各种90、95的NOIP靶形数独,结果速度确实快了好几倍恩恩。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <vector>
- using namespace std;
- const int MAXC = + ;
- const int MAXR = + ;
- const int MAXP = MAXR * + MAXC;
- const int p[][] = {
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,},
- {,,,,,,,,}
- };
- struct DLX {
- int n, sz;//列数,结点总数
- int sum[MAXC];//每列拥有的结点数
- int row[MAXP], col[MAXP], get[MAXP];//结点所在的行和列
- int left[MAXP], right[MAXP], up[MAXP], down[MAXP];//十字链表
- int ans;
- void init(int nn) {
- n = nn;
- for(int i = ; i <= n; ++i) {
- up[i] = down[i] = i;
- left[i] = i - ; right[i] = i + ;
- }
- right[n] = ; left[] = n;
- sz = n + ;
- memset(sum, , sizeof(sum));
- }
- void add_row(int r, int _get, vector<int> columns) {
- int first = sz;
- for(int i = , len = columns.size(); i < len; ++i) {
- int c = columns[i];
- left[sz] = sz - ; right[sz] = sz + ; down[sz] = c; up[sz] = up[c];
- down[up[c]] = sz; up[c] = sz;
- row[sz] = r; col[sz] = c; get[sz] = _get;
- ++sum[c]; ++sz;
- }
- right[sz - ] = first; left[first] = sz - ;
- }
- void remove(int c) {
- left[right[c]] = left[c];
- right[left[c]] = right[c];
- for(int i = down[c]; i != c; i = down[i])
- for(int j = right[i]; j != i; j = right[j]) {
- up[down[j]] = up[j]; down[up[j]] = down[j]; --sum[col[j]];
- }
- }
- void restore(int c) {
- for(int i = up[c]; i != c; i = up[i])
- for(int j = left[i]; j != i; j = left[j]) {
- up[down[j]] = j; down[up[j]] = j; ++sum[col[j]];
- }
- left[right[c]] = c;
- right[left[c]] = c;
- }
- void dfs(int d, int score) {
- if(right[] == ) {
- ans = max(ans, score);
- return ;
- }
- int c = right[];
- for(int i = right[]; i != ; i = right[i]) if(sum[i] < sum[c]) c = i;
- remove(c);
- for(int i = down[c]; i != c; i = down[i]) {
- for(int j = right[i]; j != i; j = right[j]) remove(col[j]);
- dfs(d + , score + get[i]);
- for(int j = left[i]; j != i; j = left[j]) restore(col[j]);
- }
- restore(c);
- }
- int solve() {
- ans = -;
- dfs(, );
- return ans;
- }
- };
- DLX solver;
- const int SLOT = ;
- const int ROW = ;
- const int COL = ;
- const int SUB = ;
- inline int encode(int a, int b, int c) {
- return a * + b * + c + ;
- }
- int puzzle[][];
- void read() {
- for(int i = ; i < ; ++i)
- for(int j = ; j < ; ++j) scanf("%d", &puzzle[i][j]);
- }
- int main() {
- read();
- solver.init();
- for(int r = ; r < ; ++r)
- for(int c = ; c < ; ++c)
- for(int v = ; v < ; ++v)
- if(puzzle[r][c] == || puzzle[r][c] == + v) {
- vector<int> columns;
- columns.push_back(encode(SLOT, r, c));
- columns.push_back(encode(ROW, r, v));
- columns.push_back(encode(COL, c, v));
- columns.push_back(encode(SUB, (r/)*+c/, v));
- solver.add_row(encode(r, c, v), p[r][c] * ( + v), columns);
- }
- printf("%d\n", solver.solve());
- }
NOIP 2009 靶形数独(DLX)的更多相关文章
- [COGS 0407][NOIP 2009] 靶形数独
407. [NOIP2009] 靶形数独 ★★ 输入文件:sudoku.in 输出文件:sudoku.out 简单对比时间限制:5 s 内存限制:128 MB [问题描述] 小城和小华 ...
- [NOIp 2009]靶形数独
Description 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他 ...
- 靶形数独 2009年NOIP全国联赛提高组(搜索)
靶形数独 2009年NOIP全国联赛提高组 时间限制: 4 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小城和小华都是热爱数 ...
- 【NOIP 2009】靶形数独
题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的“靶 ...
- NOIp 2009:靶形数独
题目描述 Description 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向Z 博士请教, Z ...
- 洛谷 P1074 靶形数独 Label:search 不会
题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...
- NOIP2009靶形数独[DFS 优化]
描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z博士请教,Z 博士拿出了他最近发明的“靶形数独 ...
- 靶形数独(codevs 1174)
1174 靶形数独 2009年NOIP全国联赛提高组 时间限制: 4 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Descri ...
- [NOIP2009] 靶形数独(搜索+剪枝)
题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...
随机推荐
- svg了解一下
工作需求,要用svg动态生成思维导图.我的天,这是我的短板. 但是没办法,需求在这,硬着头皮上吧. 本来想偷懒,看看网上有没有现成的可以copy的,逛了一圈发现没有. 这个过程种发现了D3.Three ...
- Openresty最佳案例 | 第9篇:Openresty实现的网关权限控制
转载请标明出处: http://blog.csdn.net/forezp/article/details/78616779 本文出自方志朋的博客 简介 采用openresty 开发出的api网关有很多 ...
- 自动诊断档案库(ADR)学习
(1)ADR概述 Oracle 11g的FDI(Fault Diagnosability Infrastructure)是自动化诊断方面的一个增强,其核心组件为自动诊断库(Automatic Diag ...
- Oracle数据库 数据完整性和DML语句
数据完整性和DML语句 数据完整性 数据完整性(Data Integrity)是指数据的精确性(Accuracy) 和可靠性(Reliability).它是应防止数据库中存在不符合语义规定的数据和防止 ...
- linux 中$ 意思
grep -n sh$ text.txt 查找文件内容中以 Sh 结尾. grep -n ^a text.txt 文件文件内容中以 a 开头. grep -n ^$ text.txt ...
- Spring Boot学习笔记(二二) - 与Mybatis集成
Mybatis集成 Spring Boot中的JPA部分默认是使用的hibernate,而如果想使用Mybatis的话就需要自己做一些配置.使用方式有两种,第一种是Mybatis官方提供的 mybat ...
- Plupload+easyui+springmvc实现批量上传
demo下载(java项目):http://pan.baidu.com/s/1ntmoGEd 可兼容所有常用浏览器,当前版本为V1.5.4,如果不兼容,肯定是你没有调试好啊 1.jsp代码 <% ...
- Zabbix——异常问题处理
报错: zabbix server is not running: the information displayed may not be current 解决: selinux关闭.开启selin ...
- Linux运维工作中需要掌握的知识
说到工具,在行外可以说是技能,在行内我们一般称为工具,就是运维必须要掌握的工具.我就大概列出这几方面,这样入门就基本没问题了.linux系统如果是学习可以选用redhat或centos,特别是cent ...
- flask 中访问时后台错误 error: [Errno 32] Broken pipe
解决办法:app.run(threaded=True) 个人理解:flask默认单线程,访问一个页面时会访问到很多页面,比如一些图片,加入参数使其为多线程