UVA 1602 Lattice Animals解题思路(打表+set)
Posted 糖栗子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 1602 Lattice Animals解题思路(打表+set)相关的知识,希望对你有一定的参考价值。
题目链接 https://vjudge.net/problem/UVA-1602
紫书的一道例题,跟之前的很多题目有很多不同。
本题不像是一般的dfs或bfs这样的搜索套路,而是另一种枚举思路。
题意:
输入n、 w、 h(1≤n≤10,1≤w,h≤n),求能放在w*h网格里的不同的n连块的个数(平移、 旋转、 翻转后相同的图形算作同一种)。
思路:
思路很明确,生成图形后判重,加入重复表或弃掉。
本题的重点就在生成和判重。
我的思路:
连通块的生成:通过维护一个int open[10][10]={0}, vis[10][10]来记录可连通的许多块和已走块,在确定下一步时向open中添加新块的连通块(自加),在回溯时删除对应的连通块(自减)。
连通块的判重:通过move()函数平移连通块的每个块使之标准化,rote()函数旋转连通块顺时针90°,mirror()函数生成连通块镜像判断重复,同时插入重复表中。
参考思路(紫书);
连通块的生成:通过向n-1个块的重复表的各连通块中加入新块生成n个块的新图。
连通块的判重:同上,只是函数名有变。
思路二:
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <set> 5 using namespace std; 6 struct Cell{ 7 int x, y; 8 Cell(int x=0, int y=0):x(x),y(y) {} 9 bool operator < (const Cell &a) const{ 10 return x<a.x || (x==a.x && y<a.y); 11 } 12 }; 13 int maxn=10, dir[4][2]={0,1,0,-1,1,0,-1,0}; 14 int n, h, w, ans[11][11][11]={0}, vis[11][11]; 15 typedef set<Cell> Poly; 16 set<Poly> state[11]; 17 18 inline Poly move(Poly &p){ 19 int mx=maxn, my=maxn; 20 Poly p2; 21 for (Poly::iterator c=p.begin(); c!=p.end(); ++c){ 22 if (mx>c->x) mx=c->x; 23 if (my>c->y) my=c->y; 24 } 25 for (Poly::iterator c=p.begin(); c!=p.end(); ++c) 26 p2.insert(Cell(c->x-mx, c->y-my)); 27 return p2; 28 } 29 30 inline Poly rote(Poly &p){ 31 Poly p2; 32 for (Poly::iterator c=p.begin(); c!=p.end(); ++c) 33 p2.insert(Cell(c->y, -(c->x))); 34 return move(p2); 35 } 36 37 inline Poly mirror(Poly &p){ 38 Poly p2; 39 for (Poly::iterator c=p.begin(); c!=p.end(); ++c) 40 p2.insert(Cell(c->x, -(c->y))); 41 return move(p2); 42 } 43 44 void check(Poly p, Cell &c){ 45 p.insert(c); 46 p=move(p); 47 if (state[n].count(p)) return; 48 for (int i=0; i<3; i++){ 49 p=rote(p); 50 if (state[n].count(p)) return; 51 } 52 p=mirror(p); 53 if (state[n].count(p)) return; 54 for (int i=0; i<3; i++){ 55 p=rote(p); 56 if (state[n].count(p)) return; 57 } 58 p=move(p); 59 state[n].insert(p); 60 } 61 62 void pre(void){ 63 Poly p; 64 p.insert(Cell(0, 0)); 65 state[1].insert(p); 66 67 for (n=2; n<=maxn; n++) 68 for (set<Poly>::iterator p=state[n-1].begin(); p!=state[n-1].end(); ++p) 69 for (Poly::iterator c=(*p).begin(); c!=(*p).end(); ++c) 70 for (int j=0; j<4; j++){ 71 Cell nc((c->x)+dir[j][0], (c->y)+dir[j][1]); 72 if (!(p->count(nc))) check(*p, nc); 73 } 74 for (n=2; n<=maxn; n++){ 75 for (set<Poly>::iterator p=state[n].begin(); p!=state[n].end(); ++p){ 76 int maxx=0, maxy=0; 77 for (Poly::iterator c=(*p).begin(); c!=(*p).end(); ++c){ 78 if (maxx<(c->x)) maxx=(c->x); 79 if (maxy<(c->y)) maxy=(c->y); 80 } 81 if (maxx>maxy) ans[n][maxx+1][maxy+1]++; 82 else ans[n][maxy+1][maxx+1]++; 83 } 84 } 85 } 86 87 int show(int w, int h){ 88 int spr=(w>h)?w:h, mnr=(w!=spr)?w:h, re=0; 89 for (int i=1; i<=spr; i++) 90 for (int j=1; j<=mnr; j++) 91 if (i>=j) re+=ans[n][i][j]; 92 return re; 93 } 94 95 int main(void){ 96 pre(); 97 98 while(scanf("%d%d%d", &n, &h, &w)==3 && n) 99 printf("%d\\n", (n==1)?1:show(w, h)); 100 101 return 0; 102 }
因为思路一的代码bug还没解决,等AC了就交上来。: )
以上是关于UVA 1602 Lattice Animals解题思路(打表+set)的主要内容,如果未能解决你的问题,请参考以下文章
UVA 1602 Lattice Animals解题思路(打表+set)
例题 7-14 UVA-1602Lattice Animals
UVA - 1602 Lattice Animals (暴力+同构判定)