博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA - 1602 Lattice Animals (暴力+同构判定)
阅读量:5069 次
发布时间:2019-06-12

本文共 2264 字,大约阅读时间需要 7 分钟。

题意:求能放进w*h的网格中的不同的n连通块个数(通过平移/旋转/翻转后相同的算同一种),1<=n<=10,1<=w,h<=n。

刘汝佳的题真是一道比一道让人自闭...QAQ~~

这道题没什么好的办法,Polya定理也毫无用武之地,只能暴力构造出所有可能的连通块,然后用set判重,比较考验基本功。

连通块可以用一个结构体D来表示,D的n代表黑块数量,然后有至多10个点P(x,y),用另一个结构体数组P[N]来表示。

问题的关键在于如何判重。

首先要知道set是通过<运算符来判重的,因此肯定要重载一下<运算符。既然要重载<运算符,那么就需要能比较出两个连通块的大小来。

如何比较两个黑块数量相同的连通块的大小呢?可以类比向量的字典序大小比较法,把所有的黑块按照x从小到大排序,x相同的按y从小到大排序,就可以比较大小了。

但是同构的两个连通块之间是不具有大小关系的,因此要先想办法把同构的连通块弄成统一的样子。

考虑三类等价变换:

1.平移:$(x,y)\leftrightarrow(x+a,y+b)$

2.旋转:$(x,y)\leftrightarrow(-y,x)$

3.翻转:$(x,y)\leftrightarrow(-x,y)$

所有同构的连通块都可以通过以上三类变换相互得到,对于同构的连通块,可以只保留其中字典序最小的。由于通过旋转和翻转能构造出的不同连通块只有8种,因此可以枚举这8中连通块,然后平移到左上角,取其中字典序最小的即可。

注意在比较字典序的时候,正反都要比较一下。(某人因为忘了反着比较而花了两个小时写了一整页代码来debug~~)

然后就没什么特别需要注意的了,设st[i][j][k]为用i个黑块能构造出j*k(j<=k)的异构连通块的集合,递推搞一搞就行了。

代码:(七重for循环,大概是我写过的层数最多的for循环了~~UVA的评测机也很给力,本地要跑300+ms,交上去30ms就过了)

1 #include
2 using namespace std; 3 typedef long long ll; 4 const int N=10+2,inf=0x3f3f3f3f; 5 const int dx[]= {
0,0,-1,1}; 6 const int dy[]= {-1,1,0,0}; 7 //格点 8 struct P { 9 int x,y; 10 bool operator==(const P& b)const {
return x==b.x&&y==b.y;} 11 bool operator<(const P& b)const {
return x!=b.x?x
norm(),b=a; 50 for(int i=0; i<2; ++i,b=b.flip()) 51 for(int j=0; j<4; ++j,b=b.rot()) { 52 b=b.norm(); 53 if(b
st[N][N][N]; 59 int n,w,h,ans; 60 61 int main() { 62 D t(1); 63 t.p[0]= {
0,0}; 64 st[1][1][1].insert(t); 65 for(int _=1; _<10; ++_) { 66 for(int i=1; i<=10; ++i) 67 for(int j=i; j<=10; ++j) { 68 for(D t:st[_][i][j]) { 69 t.n++; 70 for(int k=0; k
ty)swap(tx,ty); 85 st[_+1][tx][ty].insert(t.minimum()); 86 } 87 } 88 } 89 } 90 } 91 while(scanf("%d%d%d",&n,&w,&h)==3) { 92 ans=0; 93 if(w>h)swap(w,h); 94 for(int i=1; i<=w; ++i) 95 for(int j=1; j<=h; ++j) 96 ans+=st[n][i][j].size(); 97 printf("%d\n",ans); 98 } 99 return 0;100 }

 

转载于:https://www.cnblogs.com/asdfsag/p/10367482.html

你可能感兴趣的文章
编写KPI总结
查看>>
《程序设计与数据结构》第9周学习总结
查看>>
基于之前做的一个Demo,总结一下c#操作WebBrowse的一些技巧
查看>>
Python语法基础:字符串
查看>>
靶形数独(codevs 1174)
查看>>
Leetcode 1029. 可被 5 整除的二进制前缀
查看>>
[调参]CV炼丹技巧/经验
查看>>
[贪心] COJ 1236 删数游戏
查看>>
Django简介
查看>>
Git 使用教程(2)
查看>>
js判断undefined类型
查看>>
SIP头域说明
查看>>
011. 解决VS2015中CS1528: Expected ; or = (cannot specify constructor arguments in declaration)
查看>>
第 39 章 ThinkPHP--模型初步
查看>>
redis 基本原理及安装
查看>>
3 - 8 字典的使用
查看>>
vscode断点调试工程化客户端文件
查看>>
flask数据库管理
查看>>
使用transition实现图片动画墙效果
查看>>
abp zero mysql版正式发布
查看>>