多联骨牌的生成办法,维基上只找到固定的骨牌fix,而free的没有找到。

于是只好写个set判重的简单枚举了。

旋转的操作,可以在坐标轴上画个点,以原点为轴心,逆时针旋转90度,新的点的坐标为(-y,x)。顺时针也差不多。

反转类似。

对于操作完的骨牌,还要进行标准化,取最小的横纵坐标为参考,求出新的坐标,以便于判断。

生成所有骨牌以后,预处理一下(一顿乱搞)就好了。

#include<bits/stdc++.h>
using namespace std; #define local const int maxn = ; struct Cell
{
int x,y;
Cell(int x = ,int y = ):x(x),y(y){}
bool operator < (const Cell & rhs) const {
return x < rhs.x||(x == rhs.x && y < rhs.y);
}
};
#define FOR_CELL(c, p) for(Polyomino::const_iterator c = (p).begin(); c != (p).end(); ++c) typedef set<Cell> Polyomino; inline void normalize(Polyomino *px){
int minx = px->begin()->x, miny = px->begin()->y;
Polyomino::const_iterator c;
for(c = px->begin(); c != px->end(); ++c) {
minx = min(minx, c->x);
miny = min(miny, c->y);
}
Polyomino pn;
for(c = px->begin(); c != px->end(); ++c){
pn.insert(Cell(c->x-minx,c->y-miny));
}
*px = pn;
} inline void Rotate(Polyomino & px) {
Polyomino p2;
Polyomino::const_iterator c;
for(c = px.begin(); c != px.end(); ++c)
p2.insert(Cell(c->y,-c->x));
px = p2;
normalize(&px);
} inline void flip(Polyomino &px) {
Polyomino p3;
Polyomino::const_iterator c;
for(c = px.begin(); c != px.end(); ++c)
p3.insert(Cell(-c->x,c->y));
normalize(&p3);
px = p3;
} set<Polyomino>poly[maxn]; void check(const Polyomino &p0,Cell& newCell){
Polyomino p = p0;
p.insert(newCell);
normalize(&p);
int n = p.size();
for(int i = ; i < ; i++){
if(poly[n].count(p)) return;
Rotate(p);
}
flip(p);
for(int i = ; i < ; i++){
if(poly[n].count(p)) return;
Rotate(p);
}
poly[p.size()].insert(p);
} int ans[maxn][maxn][maxn]; struct whc
{
int w,h,c;
whc(){}
whc(int w,int h,int c):w(w),h(h),c(c){}
}; int SIZE[maxn] = {};
whc V[maxn][]; void generatePoly(){
const int dx[] = {,,,-};
const int dy[] = {,-,,};
Polyomino s;
s.insert(Cell(,));
poly[].insert(s); for(int i = ; i < maxn-; i++){
for(set<Polyomino>::iterator it = poly[i].begin(); it != poly[i].end(); it++ ){
FOR_CELL(c,*it){
for(int dir = ; dir < ; dir++){
Cell newc(c->x+dx[dir],c->y+dy[dir]);
if(it->count(newc) == ) check(*it,newc);
}
}
}
} int mp[maxn][maxn][maxn] = {};
for(int n = ; n < maxn; n++){
SIZE[n] = ;
for(set<Polyomino>::iterator it = poly[n].begin(); it != poly[n].end(); it++ ){
int maxx,maxy; maxx = maxy = ;
FOR_CELL(c,*it){
maxx = max(maxx,c->x);
maxy = max(maxy,c->y);
}
if(maxy<maxx) swap(maxx,maxy);
mp[n][maxx][maxy]++;
}
} for(int n = ; n < maxn; n++){
for(int w = ; w < n; w++)
for(int h = w; h < n; h++){
if(mp[n][w][h]){
V[n][SIZE[n]++] = whc(w,h,mp[n][w][h]);
}
}
} } inline int ANS(int n,int w,int h){
if(~ans[n][w][h]) return ans[n][w][h];
else {
int cnt = ;
whc *a = V[n];
for(int i = , sz =SIZE[n] ; i < sz; i++ ){
whc & u = a[i];
if(u.w < w && u.h < h) cnt += u.c;
}
return ans[n][w][h] = cnt;
}
} int main()
{
#ifdef local
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif // local
generatePoly();
memset(ans,-,sizeof(ans));
int n,w,h;
while(~scanf("%d%d%d",&n,&w,&h)){
if(h<w) swap(w,h);
printf("%d\n",ANS(n,w,h));
}
return ;
}

UVA1602 Lattice Animals 网格动物 (暴力,STL)的更多相关文章

  1. UVA-1602 Lattice Animals 搜索问题(打表+set)

    题目链接 https://vjudge.net/problem/UVA-1602 紫书的一道例题,跟之前的很多题目有很多不同. 本题不像是一般的dfs或bfs这样的搜索套路,而是另一种枚举思路. 题意 ...

  2. UVA1602 Lattice Animals 搜索+剪枝

    题目大意 给出一个$w\times h$的网格,定义一个连通块为一个元素个数为$n$的方格的集合$A,\forall x\in A, \exists y\in A$,使得$x,y$有一条公共边.现要求 ...

  3. ACM题目————网格动物

    Lattice animal is a set of connected sites on a lattice. Lattice animals on a square lattice are esp ...

  4. 【DFS】【打表】Lattice Animals

    [ZOJ2669]Lattice Animals Time Limit: 5 Seconds      Memory Limit: 32768 KB Lattice animal is a set o ...

  5. UVA - 1602 Lattice Animals (暴力+同构判定)

    题目链接 题意:求能放进w*h的网格中的不同的n连通块个数(通过平移/旋转/翻转后相同的算同一种),1<=n<=10,1<=w,h<=n. 刘汝佳的题真是一道比一道让人自闭.. ...

  6. 网格动物UVA1602

    题目大意 输入n,w,h(1<=n<=10,1<=w,h<=n).求能放在w*h网格里的不同的n连块的个数(平移,旋转,翻转算一种) 首先,方法上有两个,一是打表,dfs构造连 ...

  7. 【例题 7-14 UVA-1602】Lattice Animals

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 借鉴网上的题解的. 思路是. 用"标准化"的思想. 确定基准点(0,0) 然后假设(0,0)是第一个连通块. 然 ...

  8. UVa 1602 Lattice Animals (STL && 生成n连块 && 无方向形状判重)

    题意 : 给定一个 w * h 的 矩阵,在矩阵中找不同n个连通块的个数(旋转,翻转,平移算作一种) 分析 : 这题的关键点有两个 ① 生成n连块并且存储起来(因为题目是多测试用例,如果每一次都重新生 ...

  9. UVA 1602 Lattice Animals

    题目 输入n.w.h($1\leqslant n \leqslant 10, 1\leqslant w,h \leqslant n$),求能放在w*h网格里的不同的n连块的个数(注意,平移.旋转.翻转 ...

随机推荐

  1. c的scanf为什么比c++的cin快

    很早就知道,c的scanf(printf)比c++的快.刷题时尤其明显,在这上面超时是常有的事儿. 但,这是别人告诉我的,c快. 为什么快? 从网上借鉴一个例子做个简单测试: 1.cpp     // ...

  2. SPFA算法——最短路径

    粗略讲讲SPFA算法的原理,SPFA算法是1994年西南交通大学段凡丁提出 是一种求单源最短路的算法 算法中需要用到的主要变量 int n;  //表示n个点,从1到n标号 int s,t;  //s ...

  3. nginx是如何处理一个请求的(包含https配置)

    配置https首先要有ssl证书,这个证书目前阿里有免费的,但如果自己做实验,也是可以自签证书,只不过不受信 openssl genrsa -des3 -out server.key 1024     ...

  4. ApplicationContext的三个常用实现类:

    ClassPathXmlApplicationContext 它可以加载类路径下的配置文件,要求配置文件必须在类路径下,不在的话加载不了 (java中获取类路径下资源的方式) FileSystemXm ...

  5. 盛大游戏技术总监徐峥:Unity引擎使用的三种方式

    在5月13日Unite 2017 案例分享专场上,盛大游戏技术总监徐峥分享了使用Unity引擎的三种方式,以下为详细内容: 大家好,我先简单介绍一下我自己,我是盛大游戏的技术总监徐峥.我今天想分享的主 ...

  6. 【转】oracle的分析函数over

    源地址:http://www.cnblogs.com/sumsen/archive/2012/05/30/2525800.html

  7. uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵加速)

    传送门 uoj上的数据太毒了--也可能是我人傻常数大的缘故-- 三种血量的奴隶主加起来不超过\(8\)个,可以枚举每种血量的奴隶主个数,那么总的状态数只有\(165\)种,设\(dp_{t,i,j,k ...

  8. Java:创建线程

    Java定义了两种创建线程的方法: 1.实现Runnable接口 要实现Runnable接口,只需简单地实现run()方法即可,声明如下:public void run() 在run()方法中,可以定 ...

  9. 部署Azure Log Analytics

    Azure Log Analytics功能用于收集并处理Azure资源或部分本地资源的log数据,同时该功能与Azure Alert集成,可以针对搜集到的异常日志给管理人员发起报警. 1.创建Azur ...

  10. Glassfish DeploymentException: Error in linking security policy for

    http://stackoverflow.com/questions/7322476/glassfish-deploymentexception-error-in-linking-security-p ...