博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 1602 Lattice Animals
阅读量:5107 次
发布时间:2019-06-13

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

 

题意:w*h网格里放n连块,问有多少种放法

翻转、旋转90°、平移之后相同的算一种

 

推荐题解:

 

解决本题的三个问题:

1、状态的有效表示

2、状态的搜索

3、状态的判重

 

1、状态表示:set套set

定义结构体类型Cell 表示每一个格子的坐标

set<Cell>polyomino 表示一个合法的连通块 坐标 集合

set<polyomino>sp[i]  表示所有的i连块集合

这样用set里带的count() 可以方便的判重

 

2、每一个n连块都可以有一个n-1连块增加一个而来

 

3、

平移:

将连通块标准化,即连通块里坐标最小的格子(minx,miny)映射到(0,0)上去,

然后连通块整体沿向量(minx,miny)方向平移

称之为标准化

标准化之后的连通块相同,则他们可以通过平移操作相同

旋转:

现将连通块标准化

然后每次旋转90°,即坐标由(x,y)变为(y,-x)

然后再标准化

翻转:

先将连通块标准化

然后沿x轴翻转,即坐标由(x,y)变为 (x,-y)

然后再标准化

 

翻转时只需沿x轴翻转

因为沿y轴翻转可以看做 先沿x轴翻转,再旋转2次90°

对于每一种翻转、旋转、翻转之后再旋转、旋转之后再翻转

均可以有旋转和翻转的组合完成

 

所以判重的时候,先判平移

然后 旋转4次90°

然后沿x轴翻转,再旋转4次90°

 

#include
#include
#include
#include
#include
using namespace std;int ans[11][11][11];struct Cell{ int x,y; Cell(int x=0,int y=0):x(x),y(y) { } bool operator < (const Cell & rhs) const { if(x!=rhs.x) return x
polyomino;set
sp[11];const int dir_x[]={-1,1,0,0};const int dir_y[]={ 0,0,-1,1};inline polyomino normalize(const polyomino &p){ int minx=p.begin()->x,miny=p.begin()->y; for(polyomino :: const_iterator it=p.begin();it!=p.end();it++) { minx=min(minx,it->x); miny=min(miny,it->y); } polyomino tmp; for(polyomino :: const_iterator it=p.begin();it!=p.end();it++) { int x=it->x,y=it->y; tmp.insert(Cell(x-minx,y-miny)); } return tmp;}inline polyomino rotation(const polyomino &p){ polyomino tmp; for(polyomino :: const_iterator it=p.begin();it!=p.end();it++) { int x=it->x,y=it->y; tmp.insert(Cell(y,-x)); } return normalize(tmp);}inline polyomino flip_x(const polyomino &p){ polyomino tmp; for(polyomino :: const_iterator it=p.begin();it!=p.end();it++) { int x=it->x,y=it->y; tmp.insert(Cell(x,-y)); } return normalize(tmp); } void set_poly(const polyomino & p,const Cell &c){ polyomino tmp=p; tmp.insert(c); tmp=normalize(tmp); int n=tmp.size(); for(int i=0;i<4;i++) { if(sp[n].count(tmp)) return; tmp=rotation(tmp); } tmp=flip_x(tmp); for(int i=0;i<4;i++) { if(sp[n].count(tmp)) return; tmp=rotation(tmp); } sp[n].insert(tmp);}void make_Ans_List(){ polyomino cur; cur.insert(Cell(0,0)); sp[1].insert(cur); for(int n=1;n<=10;n++) for(set
::iterator it=sp[n-1].begin();it!=sp[n-1].end();it++) for(polyomino ::const_iterator cit=(*it).begin();cit!=(*it).end();cit++) for(int dir=0;dir<4;dir++) { Cell newc(cit->x+dir_x[dir],cit->y+dir_y[dir]); if((it->count(newc))==0) set_poly(*it,newc); } for(int n=1;n<=10;n++) for(int w=1;w<=10;w++) for(int h=1;h<=10;h++) { int cnt=0; for(set
::iterator it=sp[n].begin();it!=sp[n].end();it++) { int maxx=0,maxy=0; for(polyomino :: const_iterator c=(*it).begin();c!=(*it).end();c++) { maxx=max(maxx,c->x); maxy=max(maxy,c->y); } if(min(maxx,maxy)
w*h) printf("0\n"); else printf("%d\n",ans[n][w][h]); }}

 

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/7668659.html

你可能感兴趣的文章
Navicat MySQL安装
查看>>
Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)
查看>>
面向对象:输出对象、克隆对象、加载类
查看>>
(021)VMWare副虚拟磁盘和子虚拟磁盘id不匹配
查看>>
读取当前目录下CIniFile类文件
查看>>
file协议
查看>>
leetcode刷题笔记326 3的幂
查看>>
20145308 《网络对抗》 Web应用 学习总结
查看>>
AIDL学习
查看>>
数据库之完整性约束条件
查看>>
VC 解密OUTLOOK pop3保存注册表密码
查看>>
任意结点间距离
查看>>
linux面试
查看>>
网页显示电子表
查看>>
sklearn学习8-----GridSearchCV(自动调参)
查看>>
IIS7下swfupload上传大文件出现404错误
查看>>
第四章 javaScript运算符
查看>>
React Native 接入微博、微信、QQ 登录功能
查看>>
Confluence 6 Oracle 连接问题解决
查看>>
Confluence 6 识别系统属性
查看>>