小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低。但普通的数独对他们来说都过于简单了,于是他们向Z 博士请教,Z 博士拿出了他最近发明的“靶形数独”,作为这两个孩子比试的题目。
靶形数独的方格同普通数独一样,在 9 格宽×9 格高的大九宫格中有9 个3 格宽×3 格高的小九宫格(用粗黑色线隔开的)。在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入1 到9 的数字。每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。但靶形数独有一点和普通数独不同,即每一个方格都有一个分值,而且如同一个靶子一样,离中心越近则分值越高。

上图具体的分值分布是:最里面一格(黄色区域)为 10 分,黄色区域外面的一圈(红色区域)每个格子为9 分,再外面一圈(蓝色区域)每个格子为8 分,蓝色区域外面一圈(棕色区域)每个格子为7 分,最外面一圈(白色区域)每个格子为6 分,如上图所示。比赛的要求是:每个人必须完成一个给定的数独(每个给定数独可能有不同的填法),而且要争取更高的总分数。而这个总分数即每个方格上的分值和完成这个数独时填在相应格上的数字的乘积的总和。如图,在以下的这个已经填完数字的靶形数独游戏中,总分数为2829。游戏规定,将以总分数的高低决出胜负。

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

输入描述 Input Description
一共 9 行。每行9 个整数(每个数都在0—9 的范围内),表示一个尚未填满的数独方
格,未填的空格用“0”表示。每两个数字之间用一个空格隔开。

输出描述 Output Description
输出可以得到的靶形数独的最高分数。如果这个数独无解,则输出整数-1。

样例输入 Sample Input
【输入输出样例 1】

7 0 0 9 0 0 0 0 1
1 0 0 0 0 5 9 0 0
0 0 0 2 0 0 0 8 0
0 0 5 0 2 0 0 0 3
0 0 0 0 0 0 6 4 8
4 1 3 0 0 0 0 0 0
0 0 7 0 0 2 0 9 0
2 0 1 0 6 0 8 0 4
0 8 0 5 0 4 0 1 2

【输入输出样例 2】

0 0 0 7 0 2 4 5 3
9 0 0 0 0 8 0 0 0
7 4 0 0 0 5 0 1 0
1 9 5 0 8 0 0 0 0
0 7 0 0 0 0 0 2 5
0 3 0 5 7 9 1 0 8
0 0 0 6 0 1 0 0 0
0 6 0 9 0 0 0 0 1
0 0 0 0 0 0 0 0 6

样例输出 Sample Output
【输入输出样例 1】

2829

【输入输出样例 1】

2852

DLX 或者 位运算
1.DLX
每个数字当做一个精准覆盖问题,再处理九宫格
2.位运算
二进制处理矩阵

位运算:

#include <iostream>
#include <cstdlib>
#include <cstdio>using namespace std;const int mlen = 10;
int a[mlen][mlen],b[mlen][mlen];
int row[mlen],lie[mlen],line[mlen],ma[mlen];
int f[512],ans,node[mlen],cnt[mlen];void init() {for(int i = 0; i < 9; i++) b[i][0] = b[0][i] = b[8][i] = b[i][8] = 6;for(int i = 1; i < 8; i++) b[i][1] = b[1][i] = b[7][i] = b[i][7] = 7;for(int i = 2; i < 7; i++) b[i][2] = b[2][i] = b[6][i] = b[i][6] = 8;for(int i = 3; i < 6; i++) b[i][3] = b[3][i] = b[5][i] = b[i][5] = 9;b[4][4] = 10; int t = 0;for(int i = 1, j = 0; i <= 511; i <<= 1, j++) f[i] = j;for(int i = 0; i < 9; i++)for(int j = 0; j < 9; j++) {scanf("%d",&a[i][j]);if(a[i][j] != 0){row[i] |= 1<<j;t = 1<<(a[i][j]-1);if((lie[i]&t) || (line[j]&t) || (ma[i/3*3+j/3]&t)) { printf("-1\n"); exit(0); }lie[i] |= t; line[j] |= t;ma[i/3*3+j/3] |= t;}else cnt[i]++;}
}inline void sore() {int nowans = 0;for(int i = 0; i < 9; i++) for(int j = 0; j < 9; j++) nowans += a[i][j]*b[i][j];if(ans < nowans) ans = nowans;
}void dfs(int t) {int pos,k;if(t == 9) { sore(); return; }int i = node[t];if(!cnt[i]) { dfs(t+1); return; }cnt[i]--;int p = (511^row[i])&(-(511^row[i]));row[i] |= p;int j = f[p];pos = 511^(lie[i]|line[j]|ma[i/3*3+j/3]);while(pos > 0) {k = pos&(-pos); pos ^= k;lie[i] |= k; line[j] |= k;ma[i/3*3+j/3] |= k; a[i][j] = f[k]+1;dfs(t);lie[i] ^= k; line[j] ^= k;ma[i/3*3+j/3] ^= k;}cnt[i]++; row[i] ^= p;
}int main() {freopen("sudoku.in","r",stdin);freopen("sudoku.out","w",stdout);init();for(int i = 0; i < 9; i++) node[i] = i;for(int i = 0; i < 9; i++)for(int j = i+1; j < 9; j++)if(cnt[node[i]] > cnt[node[j]]) node[i] ^= node[j], node[j] ^= node[i], node[i] ^= node[j];int tot = 0;while(!cnt[node[tot]]) tot++;dfs(tot);if(!ans) { printf("-1\n"); return 0; }printf("%d\n",ans);return 0;
}

DLX(By Anantheparty):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x));
#define M 325using namespace std;struct link2
{link2 *up,*down,*right,*left,*col;int row,count,lie;
}*head,*c[M],*lik[5*M],dizhi[5*M];int T,a[90],ans[M],sta,n,Ans;int get_num(int a)
{int x=((a-1)/9)+1,y=((a-1)%9)+1;int m1=min(x-1,9-x),m2=min(y-1,9-y),mi=min(m1,m2);return mi+6;
}void remove(link2 *C)
{C->left->right=C->right;C->right->left=C->left;link2 *i=C->down;while(i!=C){link2 *j=i->right;while(j!=i){j->up->down=j->down;j->down->up=j->up;j=j->right;j->col->count--;}i=i->down;}
}void resume(link2 *C)
{C->left->right=C;C->right->left=C;link2 *i=C->down;while(i!=C){link2 *j=i->right;while(j!=i){j->up->down=j;j->down->up=j;j=j->right;j->col->count++;}i=i->down;}
}int t;void addline(int *index,int row)
{for(int i=1;i<=4;i++){t++;lik[t]=&dizhi[t+T];if(i==1){lik[t]->left=lik[t];lik[t]->right=lik[t];}else{lik[t]->left=lik[t-1];lik[t]->right=lik[t-1]->right;lik[t-1]->right->left=lik[t];lik[t-1]->right=lik[t];}int j=index[i];c[j]->count++;lik[t]->up=c[j]->up;c[j]->up->down=lik[t];lik[t]->down=c[j];c[j]->up=lik[t];lik[t]->col=c[j];lik[t]->row=row;lik[t]->lie=j;}
}void bulid()
{int m=324;head=&dizhi[T++];for(int i=1;i<=m;i++)c[i]=&dizhi[T++];head->right=c[1];head->left=c[m];for(int i=1;i<=m;i++){c[i]->left=i==1?head:c[i-1];c[i]->right=i==m?head:c[i+1];c[i]->up=c[i]->down=c[i];c[i]->count=0;c[i]->lie=i;}for(int i=1;i<=81;i++){if(!a[i])continue;int y=(i-1)/9+1,x=(i-1)%9+1;int p1=i,p2=81+(y-1)*9+a[i];int p3=162+(x-1)*9+a[i],p4=243+((y-1)/3*3+(x-1)/3)*9+a[i];c[p1]->count=c[p2]->count=c[p3]->count=c[p4]->count=-1;c[p1]->left->right=c[p1]->right;c[p1]->right->left=c[p1]->left;c[p2]->left->right=c[p2]->right;c[p2]->right->left=c[p2]->left;c[p3]->left->right=c[p3]->right;c[p3]->right->left=c[p3]->left;c[p4]->left->right=c[p4]->right;c[p4]->right->left=c[p4]->left;}for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)for(int k=1;k<=9;k++){if(a[(i-1)*9+j])continue;int p1=(i-1)*9+j;int p2=81+(i-1)*9+k;int p3=162+(j-1)*9+k;int p4=243+((i-1)/3*3+(j-1)/3)*9+k;if(c[p1]->count==-1||c[p2]->count==-1||c[p3]->count==-1||c[p4]->count==-1)continue;int index[5]={0,p1,p2,p3,p4};addline(index,((i-1)*9+j)*10+k);}
}bool dance(int x)
{if(head->right==head){for(int i=1;i<=sta;i++)a[ans[i]/10]=ans[i]%10;//printf("%d:\n",n+1);int temp=0;for(int i=1;i<=81;i++)temp+=get_num(i)*a[i];if(temp>Ans)Ans=temp;return 0;   //就是这里}link2 *i=head->right->right;link2 *temp=head->right;while(i!=head){if(i->count<temp->count)temp=i;i=i->right;}if(temp->down==temp)return 0;remove(temp);i=temp->down;while(i!=temp){link2 *j=i->right;ans[++sta]=i->row;while(j!=i){remove(j->col);j=j->right;}if(dance(x+1))return 1;j=i->left;while(j!=i){resume(j->col);j=j->left;}ans[sta]=0;sta--;i=i->down;}resume(temp);return 0;
}int main()
{for(int i=1;i<=81;i++)scanf("%d",&a[i]);t=T=0;bulid();dance(0);if(Ans==0)cout<<-1;else cout<<Ans;
}

【NOIP2009】【DLX】【位运算】T4 靶形数独 题解相关推荐

  1. UVALive 3351 Easy and Not Easy Sudoku Puzzles 位运算~判断简单数独

    题意:给定一个9*9的数独,要求判断是否为简单数独. 数独:对于每一行每一列或者子方格内,只能填1~9这几个数,并且每个数字只能出现一次,比如说: 如果一个9*9的数独是简单数独的话,这个数独的解是独 ...

  2. P1074 靶形数独题解

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

  3. 【NOIP2009】【codevs1174】靶形数独

    problem solution codes //(如果你玩数独会怎么填呢)......启发式:把能确定的填上 #include<iostream> using namespace std ...

  4. LeetCode #1349. 参加考试的最大学生数 - 学到了:压缩状态动态规划、位运算、reduce()、str().count()

    赛题见:https://leetcode-cn.com/problems/maximum-students-taking-exam/ 我的解法是用递归实现广度优先搜索,结果是对的,但是太慢,超时了.这 ...

  5. 【位运算DFS/DLX】【HDU1426】【数独】

    题意:标准的一道数独题 DFS做法: 将横纵九宫格里的数字用位运算状态压缩,且可以通过逻辑或来确定总共有哪些数字被选择了,很方便也很快,代码如下 #include <cstdio> #in ...

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

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

  7. noip2009 靶形数独

    P1074 靶形数独 318通过 1.5K提交 题目提供者洛谷OnlineJudge 标签搜索/枚举2009NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录 题目描述 小城和小华都是热爱 ...

  8. Vijos1775 CodeVS1174 NOIP2009 靶形数独

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

  9. 超简单的位运算---再也不用担心看不懂题解了

    超简单的位运算---再也不用担心看不懂题解了 写在前面 1.原码.反码与补码------整形在计算机中的储存 2.移位操作符 3.位操作符 4.小练手 写在最后 写在前面 大家好,这里是风扇的小小笔记 ...

最新文章

  1. c++ vector clear()清除容器中所有数据
  2. 一个架构师谈什么是架构以及怎么成为一个架构师--转载
  3. 虚拟化宿主服务器网络设置,kvm虚拟化安装配置手册
  4. 小型校园网络拓扑RS配置
  5. python爬虫和医学数据_医学论文中的数据有什么软件可以对之进行收集和处理吗?爬虫?...
  6. ASP.NET Core使用功能开关控制路由访问
  7. java为什么不使用odbc_java jdbc和odbc的区别是什么?jdbc和odbc的关系是怎样的?
  8. java.util.ConcurrentModificationException错误解决方案
  9. Android 4.3 新特性
  10. mysql数据库什么情况下会锁表_mysql数据库锁的产生原因及解决办法
  11. 创建数组-直接法/增量法 namelengthmax isvarname iskeyword
  12. jquery ajax select 二级联动
  13. 企业IT基础架构设计概要
  14. 使用bs4爬取《孙子兵法》(处理string属性遇见<br>标签时提取为空)
  15. Linux align函数,linux内核中ALIGN解析(示例代码)
  16. 苹果Mac电脑L2TP连接公司内部网络失败解决方案
  17. 阿里云高级工程师认证证书终于到手了!
  18. 常用转义字符例如amp的含义
  19. 报org.apache.ibatis.binding.BindingException: Type interface com.olx.service.UserMapper is not known
  20. 山东春考计算机专业本科学校排名,山东春考大学本科排名及名单

热门文章

  1. 美国人口普查数据预测收入sklearn算法汇总3之ROC: KNN,LogisticRegression,RandomForest,NaiveBayes,StochasticGradientDece
  2. python中fig_matplotlib python:fig.figimage和fig.savefig的图形大小
  3. Linux下IP的配置_F_hawk189_新浪博客
  4. ae教程 (五)滤镜特效 (四)音频特效
  5. 家用计算机怎么样上网,如何能让自己家的电脑正确上网,自己动手丰衣足食
  6. 牛客网 剑指Offer,一些值得记住的小题(五)
  7. win7系统c0000218蓝屏报错解决
  8. Crazy Defense Heroes 如何冲入 GameFi 前 4?
  9. 计算机二级技能名称怎么写吸引人,简历中的技能怎么写
  10. 得分(Uva1585)