Vijos1775 CodeVS1174 NOIP2009 靶形数独
2017-08-14 09:46
239 查看
靶形数独
描述
小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低。但普通的数独对他们来说都过于简单了,于是他们向 Z博士请教,
Z 博士拿出了他最近发明的“靶形数独” ,作为这两个孩子比试的题目。
靶形数独的方格同普通数独一样,在 9 格宽×9 格高的大九宫格中有 9 个 3 格宽×3 格
高的小九宫格(用粗黑色线隔开的) 。在这个大九宫格中,有一些数字是已知的,根据这些
数字,利用逻辑推理,在其他的空格上填入 1到 9 的数字。每个数字在每个小九宫格内不能
重复出现,每个数字在每行、每列也不能重复出现。但靶形数独有一点和普通数独不同,即
每一个方格都有一个分值,而且如同一个靶子一样,离中心越近则分值越高。 (如图)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #define max(a, b) ((a) > (b) ? (a) : (b)) const int point[9][9] = {{6,6,6,6,6,6,6,6,6}, {6,7,7,7,7,7,7,7,6}, {6,7,8,8,8,8,8,7,6}, {6,7,8,9,9,9,8,7,6}, {6,7,8,9,10,9,8,7,6}, {6,7,8,9,9,9,8,7,6}, {6,7,8,8,8,8,8,7,6}, {6,7,7,7,7,7,7,7,6}, {6,6,6,6,6,6,6,6,6}}; const int yu[10][10] = {{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}}; inline void read(int &x) { x = 0;char ch = getchar(), c = ch; while(ch < '0' || ch > '9')c = ch, ch = getchar(); while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); if(c == '-')x = -x; } struct Node { int x, y; Node(int _x, int _y){x = _x;y = _y;} Node(){}; }tian[85]; int num[10][10],ge[10][10],col[10][10],row[10][10],cnt,ans,sum; int ok[10][10][10];//存每个方格可以填的数 bool cmp(Node a, Node b) { return a.x == b.x ? a.y > b.y :a.x > b.x; } void dfs(int now) { if((cnt - now + 1) * 90 + sum <= ans)return; if(now == cnt + 1) { ans = max(ans, sum); return; } register int x = tian[now].x, y = tian[now].y; for(register int i = ok[x][y][0];i >= 1;-- i) { int shu = ok[x][y][i]; if(num[x][y] || row[x][shu] || col[y][shu] || ge[yu[x][y]][shu])continue; row[x][shu] = col[y][shu] = ge[yu[x][y]][shu] = 1;num[x][y] = shu,sum += shu * point[x - 1][y - 1]; dfs(now + 1); sum -= shu * point[x - 1][y - 1],row[x][shu] = col[y][shu] = ge[yu[x][y]][shu] = num[x][y] = 0; } return; } int main() { for(register int i = 1;i <= 9;++ i)for(register int j = 1;j <= 9;++ j) { read(num[i][j]); if(num[i][j]) ge[yu[i][j]][num[i][j]] = row[i][num[i][j]] = col[j][num[i][j]] = 1, sum += num[i][j] * point[i - 1][j - 1]; } for(register int i = 1;i <= 9;++ i)for(register int j = 1;j <= 9;++ j) if(!num[i][j]) { for(register int k = 1;k <= 9;++ k) if(!col[j][k] && !row[i][k] && !ge[yu[i][j]][k]) ok[i][j][++ok[i][j][0]] = k; tian[++cnt] = Node(i,j); } std::sort(tian + 1, tian + 1 + cnt, cmp); ans = -1; dfs(1); printf("%d", ans); return 0; }
View Co靶形数独
相关文章推荐
- 洛谷 P1074 CODE[VS] 1174 [NOIP2009 T4] 靶形数独
- codevs1174 靶形数独(DLX)
- codevs1174 靶形数独(DLX)
- codevs1174 靶形数独
- 【vijos P1914】【codevs 3904】[NOIP2014 普及组T4]子矩阵(dfs+状压dp)
- CODEVS 1174 靶形数独
- Cpp环境【NOIP2006提高组】【Code[VS]1155】【Vijos1399】 金(精)明的预算
- 小Y的数学作业(Hankson 的趣味题)[NOIP2009提高组][Codevs1172]
- NOIP 车站分级 (luogu 1983 & codevs 3294 & vijos 1851) - 拓扑排序 - bitset
- 洛谷 P1967 Vijos P1843 CODE[VS] P3287 [NOIP2013 D1T3] 货车运输
- Cpp环境【NOIP2003 P3】【Vijos1100】【Code[VS]1090】【CQYZOS2816】加分二叉树
- vijos p1844(codevs 3288 ) 积木大赛 2013年NOIP全国联赛提高组
- codevs 1174 靶形数独 (启发式搜索)
- codevs 1174 靶形数独 2009年NOIP全国联赛提高组
- CODEVS 1174 靶形数独
- Cpp环境【NOIP2010提高组】【Vijos1777】【Code[VS]1066】【CQYZOJ1793】引水入城
- Codevs 1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组
- 洛谷 P1027 CODE[VS] 1041 [NOIP2001 T4] Car的旅行路线
- code vs 5131 求和 noip2015 (数学乱搞)
- NOIP2000普及组 计算器的改良 Codevs1015 字符串复杂处理