1602 - Lattice Animals
2015-07-12 19:36
381 查看
Lattice animal is a set of connected sites on a lattice. Lattice animals on a square lattice are especially popular subject of study and are also known as polyominoes. Polyomino is usually represented as a set of sidewise connected squares. Polyomino with n squares is called n-polyomino. In this problem you are to find a number of distinct free n-polyominoes that fit into rectangle w×h. Free polyominoes can be rotated and flipped over, so that their rotations and mirror images are considered to be the same. For example, there are 5 different pentominoes (5-polyominoes) that fit into 2×4 rectangle and 3 different octominoes (8-polyominoes) that fit into 3×3 rectangle.
Input
The input file contains several test cases, one per line. This line consists of 3 integer numbers n, w, and h ( 1n10, 1w, hn).
Output
For each one of the test cases, write to the output file a single line with a integer number – the number of distinct free n-polyominoes that fit into rectangle w×h.
Sample Input
5 1 4
5 2 4
5 3 4
5 5 5
8 3 3
Sample Output
0
5
11
12
3
我有话说:
这道题在细节上的处理是比较繁琐的。如果没有网上细致的题解,我觉得完成是很成问题的。
先是基本的思路,依靠set这个强大的工具枚举,储存,检验。把一个个单位格子编上坐标,和常见的坐标轴一样。然后就是从每个已有的格子开始在旁边不断地添上一块。并进行检验。所以难免要枚举所有的情况各种的n,w,h。最后输出。
请先把所有的外函数都先看完,并清楚它们的功能。
Input
The input file contains several test cases, one per line. This line consists of 3 integer numbers n, w, and h ( 1n10, 1w, hn).
Output
For each one of the test cases, write to the output file a single line with a integer number – the number of distinct free n-polyominoes that fit into rectangle w×h.
Sample Input
5 1 4
5 2 4
5 3 4
5 5 5
8 3 3
Sample Output
0
5
11
12
3
我有话说:
这道题在细节上的处理是比较繁琐的。如果没有网上细致的题解,我觉得完成是很成问题的。
先是基本的思路,依靠set这个强大的工具枚举,储存,检验。把一个个单位格子编上坐标,和常见的坐标轴一样。然后就是从每个已有的格子开始在旁边不断地添上一块。并进行检验。所以难免要枚举所有的情况各种的n,w,h。最后输出。
请先把所有的外函数都先看完,并清楚它们的功能。
#include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; struct Cell { int x, y; Cell(int x=0, int y=0):x(x),y(y) {}; bool operator < (const Cell& rhs) const { return x < rhs.x || (x == rhs.x && y < rhs.y); } }; typedef set<Cell> Polyomino; #define FOR_CELL(c, p) for(Polyomino::const_iterator c = (p).begin(); c != (p).end(); ++c)//定义,否则写写实在太麻烦 inline Polyomino normalize(const Polyomino &p) {//找到最小的x,y int minX = p.begin()->x, minY = p.begin()->y; FOR_CELL(c, p) { minX = min(minX, c->x); minY = min(minY, c->y); } Polyomino p2; FOR_CELL(c, p) p2.insert(Cell(c->x - minX, c->y - minY));//以此为坐标轴重新确立坐标,可以看成平移 return p2; } inline Polyomino rotate(const Polyomino &p) {//顺时针旋转 Polyomino p2; FOR_CELL(c, p) p2.insert(Cell(c->y, -c->x)); return normalize(p2); } inline Polyomino flip(const Polyomino &p) {//上下做镜面对称变换 Polyomino p2; FOR_CELL(c, p) p2.insert(Cell(c->x, -c->y)); return normalize(p2); } const int dx[] = {-1,1,0,0}; const int dy[] = {0,0,-1,1}; const int maxn = 10; set<Polyomino> poly[maxn+1];//已有的联通块 int ans[maxn+1][maxn+1][maxn+1]; //添加一个联通块,并判断他是不是新的联通块,如果是的话,加入polyonimo集合 void check_polyomino(const Polyomino& p0, const Cell& c) { Polyomino p = p0; p.insert(c); p = normalize(p); int n = p.size(); for(int i = 0; i < 4; i++) { if(poly .count(p) != 0) return; p = rotate(p); } p = flip(p); for(int i = 0; i < 4; i++) { if(poly .count(p) != 0) return; p = rotate(p); } poly .insert(p); } void generate() { Polyomino s; s.insert(Cell(0, 0)); poly[1].insert(s); // generate生成 for(int n = 2; n <= maxn; n++) { for(set<Polyomino>::iterator p = poly[n-1].begin(); p != poly[n-1].end(); ++p) FOR_CELL(c, *p) for(int dir = 0; dir < 4; dir++) { Cell newc(c->x + dx[dir], c->y + dy[dir]); if(p->count(newc) == 0) check_polyomino(*p, newc);//如果和原来的p中任意一点都不重合的话,至少来看在目前是有效的。不过要进一步检验 } }//枚举 // precompute answers //预计算的答案 for(int n = 1; n <= maxn; n++) for(int w = 1; w <= maxn; w++) for(int h = 1; h <= maxn; h++) { int cnt = 0; for(set<Polyomino>::iterator p = poly .begin(); p != poly .end(); ++p) { int maxX = 0, maxY = 0; FOR 4000 _CELL(c, *p) { maxX = max(maxX, c->x); maxY = max(maxY, c->y); } if(min(maxX, maxY) < min(h, w) && max(maxX, maxY) < max(h, w))//最理想的符合状态 ++cnt; } ans [w][h] = cnt; } } int main() { generate(); int n, w, h; while(scanf("%d%d%d", &n, &w, &h) == 3) { printf("%d\n", ans [w][h]); } return 0; }
相关文章推荐
- Java 网络编程(TCP)实现服务器与客户端1对多的随意顺 序的聊天室
- ehcache2.5后hibernate多SessionFactory报错的解决
- SNMP远程监控进程信息的OID
- 慕容小匹夫 Unity3D移动平台动态读取外部文件全解析
- oracle默认角色
- 25招教HR解决员工入职流程及风险的各种问题
- Hdu 5119 HappyMatt Friends (2014年北京现场赛H题)
- git 学习笔记5-add和commit命令
- vb.net Datagridview 下拉框应用
- oracle用户创建修改删除
- struts2 CVE-2013-4316 S2-019 Dynamic method executions Vul
- DHTMLXTree的使用
- re.findall and re.search的区别
- [LeetCode][JavaScript]Lowest Common Ancestor of a Binary Search Tree
- Keil V4.72升级到V5.1X之后
- 使用libxml解析HTML -- Hpple
- cati安装
- PAT 数据结构 04-树5. File Transfer (25)
- Sublime Text2解决中文乱码
- 程序异常处理