UVa 1602 Lattice Animals
来源:互联网 发布:淘宝直通车要怎么开 编辑:程序博客网 时间:2024/05/17 01:54
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 45 2 45 3 45 5 58 3 3
Sample Output
0511123
#include <cstdio>#include <set>#include <algorithm>using namespace std;#define maxn 10// 代表一个网格节点typedef struct cell{int x, y;//网格节点的坐标 // 构造函数cell(int x, int y){this->x = x;this->y = y;}bool operator < (const struct cell& a) const{return x < a.x || (x == a.x && y < a.y);}}cell;// 一个Polyomino就是一堆cell的集合typedef set<cell> poly;// poly_set[i]代表有i个cell的poly集合set<poly> poly_set[maxn+1];// answer[n][w][h]的答案 int answer[maxn+1][maxn+1][maxn+1];void gen_poly();void check_poly(const poly& this_p, cell& this_c);poly normalize(poly& p);poly rotate(poly& p);poly flip(poly& p);int main(){// 生成所有polygen_poly();//printf("here\n");int n, w, h;while(scanf("%d %d %d", &n, &w, &h) == 3){printf("%d\n", answer[n][w][h]);}return 0;}int dic_x[4] = {-1,0,1,0};int dic_y[4] = {0,1,0,-1};// 生成所有polyvoid gen_poly(){for(int i = 1; i <= maxn; i++)poly_set[i] = set<poly>();// 先生成有1个cell的polypoly p1;p1.insert(cell(0,0));poly_set[1].insert(p1);// 分别根据有i-1个cell的poly集合来生成有i个cell的poly集合for(int i = 2; i <= maxn; i++){// 对每个poly中的每个cell尝试在不同的四个方向增加一个cellfor(set<poly>::iterator p = poly_set[i-1].begin(); p != poly_set[i-1].end(); p++){for(poly::const_iterator q = p->begin(); q != p->end(); q++){for(int j = 0; j < 4; j++){cell new_c(q->x+dic_x[j], q->y+dic_y[j]);//cell new_c;if(p->find(new_c) == p->end()){// 检查形成的这个poly是否存在,如果不存在就加入check_poly(*p, new_c);}}}}}// 对所有n,w,h生成答案for(int i = 1; i <= maxn; i++){for(int w = 1; w <= i; w++){for(int h = 1; h <= i; h++){int count = 0;for(set<poly>::iterator p = poly_set[i].begin(); p != poly_set[i].end(); p++) {int max_x = p->begin()->x, max_y = p->begin()->y;for(poly::iterator q = p->begin(); q != p->end(); q++){if(max_x < q->x)max_x = q->x;if(max_y < q->y)max_y = q->y;}if(min(max_x, max_y) < min(w, h) && max(max_x, max_y) < max(w, h)){count++;}}/*if(count != 0)printf("answer[%d][%d][%d] = %d\n", i, w, h, count);*/answer[i][w][h] = count;}}}}// 检查形成的这个poly加上这个cell是否存在,如果不存在就加入void check_poly(const poly& this_p, cell& this_c){poly p = this_p;p.insert(this_c);// 规范化到最小点为(0,0)p = normalize(p);int n = p.size();// 检查旋转的8个方向是否存在,如果不存在就加入到poly集合for(int i = 0; i < 4; i++){if(poly_set[n].find(p) != poly_set[n].end())return;// 对该poly向右旋转90度p = rotate(p);}// 将该poly向下反转180度p = flip(p);for(int i = 0; i < 4; i++) { if(poly_set[n].find(p) != poly_set[n].end()) return; // 对该poly向右旋转90度 p = rotate(p); }poly_set[n].insert(p);}// 规范化到最小点为(0,0)poly normalize(poly& p){poly this_p;int min_x = p.begin()->x, min_y = p.begin()->y;for(poly::iterator q = p.begin(); q != p.end(); q++){if(q->x < min_x)min_x = q->x;if(q->y < min_y)min_y = q->y;}for(poly::iterator q = p.begin(); q != p.end(); q++) {this_p.insert(cell(q->x-min_x,q->y-min_y)); }return this_p;}// 对该poly向右旋转90度poly rotate(poly& p){poly this_p;for(poly::iterator q = p.begin(); q != p.end(); q++) { this_p.insert(cell(q->y,-q->x)); } return normalize(this_p);}// 将该poly向下反转180度poly flip(poly& p){poly this_p; for(poly::iterator q = p.begin(); q != p.end(); q++) { this_p.insert(cell(q->x,-q->y)); } return normalize(this_p);}
枚举所有的n连块,难点在于如何枚举,没有想出来,后来参考https://github.com/aoapc-book/aoapc-bac2nd/blob/master/ch7/UVa1602.cpp,自己实现了一遍。
难点:
1.以每个格子来扩展。先枚举1连块,在对1连块的每个格子的4个方向进行扩展,枚举2连块,依次类推。
2.将n连块表示成n个格子的集合,将所有的n连块又表示成集合,判重任务交给set.
3.判重时要将n连块进行8个方向的旋转,并且每个n连块需要规范化(左下角的格子在(0,0)).
4.得到n连块后判断是否能放进w*h的网格中,由于n连块已经规范化,得到n连块的格子最大x,y坐标,即能盛下该n连块的长和宽。
0 0
- UVa 1602 Lattice Animals
- uva 1602 Lattice Animals
- UVa 1602:Lattice Animals(BFS)
- Uva 1602 Lattice Animals (网格动物)
- UVa 1602 Lattice Animals 网格动物
- UVA 1062 Lattice Animals
- Lattice Animals UVA
- 1602 - Lattice Animals
- 1602 - Lattice Animals
- UVa1602 - Lattice Animals
- UVA1602 Lattice Animals 回溯+set判重
- 搜索 【uva1602】Lattice Animals (练习题7-14 网格动物)
- Animals
- uva 687 - Lattice Practices(暴力)
- uva 1549 - Lattice Point(暴力)
- [Uva1602][Poj2170][Zoj2669][Northeastern Europe 2004] Lattice Animals 【set+傻瓜搜索】
- Uva1602 Lattice Animals 【枚举打表+形状判重】【例题7-14】
- 例题7-14 网格动物(Lattice Animals, ACM/ICPC NEERC 2004, UVa1602)
- 黑马程序员——C语言基础篇---宏定义、数组、字符串和函数
- CacheConcurrencyStrategy 五种缓存方式 (实体类添加)
- Oracle DBMS_UTILITY.GET_HASH_VALUE
- 如何关闭U盘、移动硬盘、硬盘的自动打开功能!
- 类别中使用属性
- UVa 1602 Lattice Animals
- Elasticsearch之Nested Object
- eclipse 属性文件编辑插件
- Linux执行.sh文件,提示No such file or directory的问题的解决方法
- javaee学习之路(二十五)javascript
- Android中关于Volley的使用(一)认识Volley的架构
- 2015.4.14深复制体验
- Coroutine协程
- C#连接数据库