蓝桥杯 2012 5 方块填数
来源:互联网 发布:数据散修txt下载 编辑:程序博客网 时间:2024/04/28 18:57
“数独”是当下炙手可热的智力游戏。一般认为它的起源是“拉丁方块”,是大数学家欧拉于1783年发明的。
如图所示:6x6的小格被分为6个部分(图中用不同的颜色区分),每个部分含有6个小格(以下也称为分组)。
开始的时候,某些小格中已经填写了字母(ABCDEF之一)。需要在所有剩下的小格中补填字母。
全部填好后,必须满足如下约束:
1. 所填字母只允许是A,B,C,D,E,F 中的某一个。
2. 每行的6个小格中,所填写的字母不能重复。
3. 每列的6个小格中,所填写的字母不能重复。
4. 每个分组(参见图中不同颜色表示)包含的6个小格中,所填写的字母不能重复。
为了表示上的方便,我们用下面的6阶方阵来表示图[1.jpg]对应的分组情况(组号为0~5):
000011
022013
221113
243333
244455
445555
用下面的数据表示其已有字母的填写情况:
02C
03B
05A
20D
35E
53F
很明显,第一列表示行号,第二列表示列号,第三列表示填写的字母。行号、列号都从0开始计算。
一种可行的填写方案(此题刚好答案唯一)为:
E F C B D A
A C E D F B
D A B E C F
F B D C A E
B D F A E C
C E A F B D
你的任务是:编写程序,对一般的拉丁方块问题求解,如果多解,要求找到所有解。
【输入、输出格式要求】
用户首先输入6行数据,表示拉丁方块的分组情况。
接着用户输入一个整数n (n<36), 表示接下来的数据行数
接着输入n行数据,每行表示一个预先填写的字母。
程序则输出所有可能的解(各个解间的顺序不重要)。
每个解占用7行。
即,先输出一个整数,表示该解的序号(从1开始),接着输出一个6x6的字母方阵,表示该解。
解的字母之间用空格分开。
如果找不到任何满足条件的解,则输出“无解”
例如:用户输入:
000011022013221113243333244455445555602C03B05A20D35E53F
则程序输出:
1E F C B D AA C E D F BD A B E C FF B D C A EB D F A E CC E A F B D
再如,用户输入:
001111002113022243022443544433555553704B05A13D14C24E50C51A
则程序输出:
1D C E F B AE F A D C BA B F C E DB E D A F CF D C B A EC A B E D F2D C E F B AE F A D C BA D F B E CB E C A F DF B D C A EC A B E D F3D C F E B AA E B D C FF D A C E BB F E A D CE B C F A DC A D B F E4D C F E B AB E A D C FA D C F E BF B E A D CE F B C A DC A D B F E5D C F E B AE F A D C BA B C F E DB E D A F CF D B C A EC A E B D F6D C F E B AE F A D C BA B D F E CB E C A F DF D B C A EC A E B D F7D C F E B AE F A D C BA D B F E CB E C A F DF B D C A EC A E B D F8D C F E B AF E A D C BA D B C E FB F E A D CE B C F A DC A D B F E9D C F E B AF E A D C BA F C B E DB D E A F CE B D C A FC A B F D E
组合数学里著名的拉丁方问题,但是这题只要DFS就好了.同样采用链表优化,x方向限定,待选集合是bx
然后by, bg同时判重 y方向和 不同颜色的方块
然后DFS就好,注意同样不要在DFS中输出,先把答案存下来.这个在我的系统里面会段错误.
#include <bits/stdc++.h>using namespace std;char g[6][6], ans[6][6];list<char> bx[6];bool by[6][6], bg[6][6];struct V{ char a[6][6];};vector<V> arr;int cnt = 0;void add(){ V v; for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) v.a[i][j] = ans[i][j]; arr.push_back(v);}void dfs(int x, int y){ //if(cnt++ == 20) exit(250); //print(ans); if (ans[x][y] != '*') { y++; if (y == 6) x++, y = 0; if (x == 6) add(); else dfs(x, y); return; } for (auto it = bx[x].begin(); it != bx[x].end(); it++) { char t = *it; int tt = t - 'A'; if (by[y][tt] || bg[g[x][y]][tt]) continue; ans[x][y] = t; by[y][tt] = true; bg[g[x][y]][tt] = true; it = bx[x].erase(it); int xx = x, yy = y + 1; if (yy == 6) xx++, yy = 0; if (xx == 6) add(); else dfs(xx, yy); ans[x][y] = '*'; by[y][tt] = false; bg[g[x][y]][tt] = false; it = bx[x].insert(it, t); }}int main(){ //freopen("in", "r", stdin); for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) scanf("%c", &g[i][j]); scanf("\n"); } int n; scanf("%d\n", &n); for (int i = 0; i < 6; i++) for (char ch = 'A'; ch <= 'F'; ch++) bx[i].push_back(ch); memset(ans, '*', sizeof(ans)); while (n--) { char s[3]; scanf("%s\n", s); int x = s[0] - '0', y = s[1] - '0'; ans[x][y] = s[2]; bx[x].remove(s[2]); by[y][s[2] - 'A'] = true; bg[g[x][y]][s[2] - 'A'] = true; } dfs(0, 0); for (int k = 0; k < arr.size(); k++) { cout << k + 1 << endl; for (int i = 0; i < 6; i++) { cout << arr[k].a[i][0]; for (int j = 1; j < 6; j++) { cout << ' ' << arr[k].a[i][j]; } cout << endl; } }}
由于限制非常多,大量被减枝,实际是运行很快
- 蓝桥杯 2012 5 方块填数
- 蓝桥杯决赛 方块填数
- 蓝桥杯 方块填数 DFS搜索
- 蓝桥杯决赛之方块填数
- 方块填数
- 方块填数
- 方块填数
- 方块填数
- 方块填数
- 方块填数c++代码
- NYOJ---蛇形填数(方块填数+三角填数)
- 蛇形填数(方块填数+三角形填数)
- 编程能力提高------蛇形填数(方块填数+三角形填数)
- 编程能力提高------蛇形填数(方块填数+三角形填数) .
- 2012年第三届蓝桥杯C/C++程序设计本科B组决赛 方块填数(编程大题)
- 拉丁方块填数字
- 拉丁方块填数字
- 【蓝桥杯】【六角填数】
- aidl
- (数论)进制转换一(将十进制转换成b进制)
- mysql存储过程利用游标查询每个数据库的所有表
- 线段树—数组计算机
- 排序算法之堆排序详解(附最大堆示例代码)
- 蓝桥杯 2012 5 方块填数
- 浅谈跨域(五)——Web Sockets试用
- jsp中页面之间的跳转forward与sendRedirect的区别
- redis被黑客入侵
- 优化算法:梯度法
- java抽象类和接口的区别
- Linux下oracle数据库启动和关闭操作
- Win7旗舰版如何关闭开机磁盘自检
- .Net Standard扩展支持实例分享