CSU 1605 数独

题目大意:

9宫格每个位置都有对应的分数,填完数独后根据对应位置的分数相加之和求个最大值,不存在输出-1

说什么用位运算加速可以解决问题,但是对着标程还是T,最近学了dlx,发现这样解决数独快了很多

位运算加速我确实写不出了,直接用dlx来做这道题目

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <climits>
  7 #include <cmath>
  8
  9 using namespace std;
 10 #define N 1000
 11 #define MAXNODE 1000000
 12 const int INF = INT_MAX;
 13 const double eps = 1e-8;
 14
 15 int a[10][10];
 16 char str[5];
 17
 18 int belong[9][9] =  {
 19                         {1,1,1,2,2,2,3,3,3},
 20                         {1,1,1,2,2,2,3,3,3},
 21                         {1,1,1,2,2,2,3,3,3},
 22                         {4,4,4,5,5,5,6,6,6},
 23                         {4,4,4,5,5,5,6,6,6},
 24                         {4,4,4,5,5,5,6,6,6},
 25                         {7,7,7,8,8,8,9,9,9},
 26                         {7,7,7,8,8,8,9,9,9},
 27                         {7,7,7,8,8,8,9,9,9},
 28                     };
 29 int sc[9][9] = {
 30                     {6,6,6,6,6,6,6,6,6},
 31                     {6,7,7,7,7,7,7,7,6},
 32                     {6,7,8,8,8,8,8,7,6},
 33                     {6,7,8,9,9,9,8,7,6},
 34                     {6,7,8,9,10,9,8,7,6},
 35                     {6,7,8,9,9,9,8,7,6},
 36                     {6,7,8,8,8,8,8,7,6},
 37                     {6,7,7,7,7,7,7,7,6},
 38                     {6,6,6,6,6,6,6,6,6},
 39                };
 40
 41
 42 void printM()
 43 {
 44     for(int i=0 ; i<9 ; i++)
 45         for(int j=0 ; j<9 ; j++){
 46            if(j<8) printf("%d " , a[i][j]);
 47            else printf("%d\n" , a[i][j]);
 48         }
 49 }
 50
 51 struct DLX{
 52     int n ,m , size;
 53     int col[MAXNODE] , row[MAXNODE];
 54     int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE];
 55     int cnt_col[N] , first[N];
 56     int ans[100] , minv;
 57
 58     void init(int _n , int _m)
 59     {
 60         n = _n , m = _m;
 61         size= m ;
 62         for(int i=0 ; i<=m ; i++){
 63             L[i] = i-1 , R[i] = i+1;
 64             U[i] = D[i] = i;
 65         }
 66         L[0] = m , R[m] = 0;
 67         for(int i=1 ; i<=m ; i++) cnt_col[i] = 0;
 68         for(int i=1 ; i<=n ; i++) first[i] = -1;
 69         minv = 0;
 70     }
 71
 72     void link(int r , int c)
 73     {
 74         ++size;
 75         U[D[c]] = size , D[size] = D[c];
 76         U[size] = c , D[c] = size;
 77
 78         if(first[r]<0) L[size]=R[size]=first[r] = size;
 79         else{
 80             L[R[first[r]]] = size , R[size] = R[first[r]];
 81             L[size] = first[r] , R[first[r]] = size;
 82         }
 83         row[size] = r , col[size] = c , cnt_col[c]++;
 84     }
 85
 86     void Remove(int c)
 87     {
 88         L[R[c]] = L[c] , R[L[c]] = R[c];
 89         for(int i=D[c] ; i!=c ; i=D[i]){
 90             for(int j=R[i] ; j!=i ; j=R[j]){
 91                 U[D[j]] = U[j] , D[U[j]] = D[j];
 92                 cnt_col[col[j]]--;
 93             }
 94         }
 95     }
 96
 97     void Resume(int c)
 98     {
 99         for(int i=U[c] ; i!=c ; i=U[i]){
100             for(int j=L[i] ; j!=i ; j=L[j]){
101                 U[D[j]] = D[U[j]] = j;
102                 cnt_col[col[j]]++;
103             }
104         }
105       //  printM();
106         L[R[c]] = R[L[c]] = c;
107     }
108
109     void Dance(int d)
110     {
111         if(!R[0]){
112             int v = 0;
113             for(int i=0 ; i<d ; i++){
114                     int r = (ans[i]-1)/81;
115                     int c = ((ans[i]-1)%81)/9;
116                     a[r][c] = ((ans[i]-1)%9)+1;
117                     v+=a[r][c]*sc[r][c];
118             }
119             minv=max(minv , v);
120             return;
121         }
122         int st=R[0];
123         for(int i=R[0] ; i!=0 ; i=R[i])
124             if(cnt_col[i]<cnt_col[st])
125                 st = i;
126         Remove(st);
127         for(int i=D[st] ; i!=st ; i=D[i]){
128             ans[d] = row[i];
129             for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]);
130             Dance(d+1);
131             for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]);
132         }
133         Resume(st);
134         return ;
135     }
136
137 }dlx;
138
139
140 int main()
141 {
142   //  freopen("a.in" , "r" , stdin);
143     int T;
144     scanf("%d" , &T);
145     while(T--)
146     {
147         for(int i=0 ; i<9 ; i++){
148             for(int j=0 ; j<9 ; j++){
149                 scanf("%d" , &a[i][j]);
150             }
151         }
152         dlx.init(729 , 324);
153         for(int i=0 ; i<9 ; i++)
154             for(int j=0 ; j<9 ; j++)
155             {
156                 if(a[i][j]){
157                     dlx.link((i*9+j)*9+a[i][j] , i*9+a[i][j]);
158                     dlx.link((i*9+j)*9+a[i][j] , 81+j*9+a[i][j]);
159                     dlx.link((i*9+j)*9+a[i][j] , 162+(belong[i][j]-1)*9+a[i][j]);
160                     dlx.link((i*9+j)*9+a[i][j] , 243+i*9+j+1);
161                 }
162                 else{
163                     for(int k=1 ; k<=9 ; k++){
164                         dlx.link((i*9+j)*9+k , i*9+k);
165                         dlx.link((i*9+j)*9+k , 81+j*9+k);
166                         dlx.link((i*9+j)*9+k , 162+(belong[i][j]-1)*9+k);
167                         dlx.link((i*9+j)*9+k , 243+i*9+j+1);
168                     }
169                 }
170             }
171         dlx.Dance(0);
172         if(!dlx.minv) puts("-1");
173         else printf("%d\n" , dlx.minv);
174     }
175
176     return 0;
177 }
时间: 2024-11-10 08:31:06

CSU 1605 数独的相关文章

软件工程——数独 总结报告

开发环境 Windows10 版本号1903 VS2019 16.3.2 Intel vtune Profile 2020 Microsoft. CodeAnalysis. FxCopAnalyzers 2.9.8 测试覆盖率工具opencppcoverage RAM 16GB 3200MHz 三星 AMD Ryzen 7 2700X 3.90GHz SSD 三星 MZVLB1TOHALR-00000 相关地址 无GUI源代码仓库:https://gitee.com/wangzhankun/so

第二次作业——个人项目实战:数独

1.阅读 刚开始泛看<构建之法>的时候,还是觉得非常难理解里面的内容,特别是代码部分.后来第二次拿起这本书,从第一章开始看起,慢慢了解了"软件企业=软件+商业模式"和对软件工程的定义,但是更多地还是记忆了一遍,没有明白这里面的深意:看第二章的时候,跟着单元测试.回归测试的.效能分析的内容自己照着书上的代码敲了一敲,偶尔会出现bug,但是能得到书上所说的效果还是很开心的,效能分析,感觉就是代码的效率问题,追求高效,然后接触到了软件工程师的一套模型-个人开发流程PSP,我也尝试

洛谷 【P1074】靶形数独

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

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

#计算机#数独

数独是一项益智小游戏,规则简单易懂,但内容千变万化.这次我想要研究的是用java编程实现解数独和数独题目的生成.首先要弄清数独的游戏规则:在一个9×9的方格中分布着1-9的数字和空格,玩家在空格中填写适当的数字,使得每行.每列.9个3×3的方格中数字1-9均只出现一次. 对于解数独初步构思的时候我产生了两种想法: 第一种想法利用计算机强大的运算能力,遍历当前空格所有可以填入的数字,向后递归,当某个空格不能填入数字,而空格数不为零时返回上一步.如果某一步只能填入一个确定的数字,可以把这一步优先填好

CSU 1111: 三家人【有趣的思维题】

1111: 三家人 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 2241  Solved: 874 [Submit][Status][Web Board] Description 有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园.A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕.C 太太因为正身怀六甲无法加入她们的行列,便出了90元.请问这笔钱如何分给A.B 二位太太较为恰当?A 应得多少元?90/(5+4)*5=$50

CSU 1112: 机器人的指令【模拟题】

1112: 机器人的指令 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 1858  Solved: 682 [Submit][Status][Web Board] Description 数轴原点有一个机器人.该机器人将执行一系列指令,你的任务是预测所有指令执行完毕之后它的位置. ·LEFT:往左移动一个单位 ·RIGHT: 往右移动一个单位 ·SAME AS i: 和第i 条执行相同的动作.输入保证i 是一个正整数,且不超过之前执行指令数 In

安卓旅途之——开发数独(一)

安卓旅途之——开发数独(一) 数独游戏简介 数独游戏,是一种数学智力拼图游戏,是“独立的数字游戏”的简称,源自18世纪末的瑞士,后在美国发展,在日本得以发扬光大. 数独游戏可以训练玩家的逻辑推理能力,不少教育者皆认为数独是锻炼脑筋的好方法. 其规则如下: 1.游戏会从一个部分带有数字的九宫格开始. 在9×9的大九宫格(即3格宽×3格高)方阵里,每一格又细分为一个小九宫格. 2.游戏开始,已给定若干数字,其它宫位留白,玩家需要自己按照逻辑推敲出剩下的空格里是什么数字. 3.填数字时必须满足以下条件

使用AxureRP7.0制作经典数独小游戏原型,axure游戏原型下载

之前,有同学在Q群中提问,如何使用axure制作经典数独解谜小游戏,当时由于时间关系没有来得及亲手制作,而是给同学们提供了Axure6.5版本的一个数独解谜游戏的原型,本教程由axure原型库网站录制,转载请注明出处!但是那个原型做的太过繁杂,所以仅供大家参考交流:在此,金乌老师特地抽时间给同学们使用AxureRP7.0制作了一下,感觉对实战逻辑分析和axure变量的掌握比较有考验,所以就放出来供大家学习交流使用. 在学习的过程中,如果你仅凭自己现有的对axure的掌握,无法准确分析并组织出原型