题目链接 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个块的新图。

连通块的判重:同上,只是函数名有变。

思路二:

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
struct Cell{
int x, y;
Cell(int x=, int y=):x(x),y(y) {}
bool operator < (const Cell &a) const{
return x<a.x || (x==a.x && y<a.y);
}
};
int maxn=, dir[][]={,,,-,,,-,};
int n, h, w, ans[][][]={}, vis[][];
typedef set<Cell> Poly;
set<Poly> state[]; inline Poly move(Poly &p){
int mx=maxn, my=maxn;
Poly p2;
for (Poly::iterator c=p.begin(); c!=p.end(); ++c){
if (mx>c->x) mx=c->x;
if (my>c->y) my=c->y;
}
for (Poly::iterator c=p.begin(); c!=p.end(); ++c)
p2.insert(Cell(c->x-mx, c->y-my));
return p2;
} inline Poly rote(Poly &p){
Poly p2;
for (Poly::iterator c=p.begin(); c!=p.end(); ++c)
p2.insert(Cell(c->y, -(c->x)));
return move(p2);
} inline Poly mirror(Poly &p){
Poly p2;
for (Poly::iterator c=p.begin(); c!=p.end(); ++c)
p2.insert(Cell(c->x, -(c->y)));
return move(p2);
} void check(Poly p, Cell &c){
p.insert(c);
p=move(p);
if (state[n].count(p)) return;
for (int i=; i<; i++){
p=rote(p);
if (state[n].count(p)) return;
}
p=mirror(p);
if (state[n].count(p)) return;
for (int i=; i<; i++){
p=rote(p);
if (state[n].count(p)) return;
}
p=move(p);
state[n].insert(p);
} void pre(void){
Poly p;
p.insert(Cell(, ));
state[].insert(p); for (n=; n<=maxn; n++)
for (set<Poly>::iterator p=state[n-].begin(); p!=state[n-].end(); ++p)
for (Poly::iterator c=(*p).begin(); c!=(*p).end(); ++c)
for (int j=; j<; j++){
Cell nc((c->x)+dir[j][], (c->y)+dir[j][]);
if (!(p->count(nc))) check(*p, nc);
}
for (n=; n<=maxn; n++){
for (set<Poly>::iterator p=state[n].begin(); p!=state[n].end(); ++p){
int maxx=, maxy=;
for (Poly::iterator c=(*p).begin(); c!=(*p).end(); ++c){
if (maxx<(c->x)) maxx=(c->x);
if (maxy<(c->y)) maxy=(c->y);
}
if (maxx>maxy) ans[n][maxx+][maxy+]++;
else ans[n][maxy+][maxx+]++;
}
}
} int show(int w, int h){
int spr=(w>h)?w:h, mnr=(w!=spr)?w:h, re=;
for (int i=; i<=spr; i++)
for (int j=; j<=mnr; j++)
if (i>=j) re+=ans[n][i][j];
return re;
} int main(void){
pre(); while(scanf("%d%d%d", &n, &h, &w)== && n)
printf("%d\n", (n==)?:show(w, h)); return ;
}

因为思路一的代码bug还没解决,等AC了就交上来。: )

UVA-1602 Lattice Animals 搜索问题(打表+set)的更多相关文章

  1. UVA 1602 Lattice Animals

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

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

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

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

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

  4. UVA1602 Lattice Animals 搜索+剪枝

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

  5. 【DFS】【打表】Lattice Animals

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

  6. UVa 1583 Digit Generator --- 水题+打表

    UVa 1583 题目大意:如果x加上x的各个数字之和得到y,那么称x是y的生成元. 给定数字n,求它的最小生成元 解题思路:可以利用打表的方法,提前计算出以i为生成元的数,设为d,并保存在a[d]中 ...

  7. UVA 11768 - Lattice Point or Not(数论)

    UVA 11768 - Lattice Point or Not option=com_onlinejudge&Itemid=8&page=show_problem&categ ...

  8. 按enter 进行搜索 enter提交表单

    //按enter 进行搜索 document.onkeydown = function(e){ var ev = document.all ? window.event : e; if(ev.keyC ...

  9. UVA.129 Krypton Factor (搜索+暴力)

    UVA.129 Krypton Factor (搜索+暴力) 题意分析 搜索的策略是:优先找长串,若长串不合法,则回溯,继续找到合法串,直到找到所求合法串的编号,输出即可. 注意的地方就是合法串的判断 ...

随机推荐

  1. Python-超好用的Django源码解析

    http://djangobook.py3k.cn/2.0/

  2. Jmeter--Timer设置等待时间

    一.Jmeter定时器的概念:1)定时器是在每个sampler(采样器)之前执行的,而不是之后:是的,你没有看错,不管这个定时器的位置放在sampler之后,还是之下,它都在sampler之前得到执行 ...

  3. HDU 1348 Wall ( 凸包周长 )

    链接:传送门 题意:给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入 思路:城墙与城堡直线长度是相等的, ...

  4. HDU 2078 选课时间( 水题 )

    链接:传送门 思路:水题略 /************************************************************************* > File N ...

  5. linux下的查找命令

    whereis <程序名称> 查找软件的安装路径 -b 只查找二进制文件 -m 只查找帮助文件 -s 只查找源代码 -u 排除指定类型文件 -f 只显示文件名 -B <目录> ...

  6. 硬核官宣:台积电官宣6nm及7nm加强版工艺!

    台积电正式宣布了6nm(N6)工艺,在已有7nm(N7)工艺的基础上大幅度增强,号称可提供极具竞争力的高性价比,而且能加速产品研发.量产.上市速度. 这几年,曾经执行业牛耳的Intel在新工艺方面进展 ...

  7. elastic学习笔记

    要点 不同工具之间版本匹配很重要由点及面,先实践起来再学细节的原理和使用 技术栈 laravel5.5框架+scout组件+elasticsearch6.3.0搜索引擎 辅助 elasticsearc ...

  8. C#调用带结构体指针的C Dll的方法【转】

    发现一篇文章关于C#调用DALL动态链接库的函数的,复制下来学习用.感谢作者的分析,原文传送门:https://www.cnblogs.com/ye-ming/p/8004314.html 在C#中调 ...

  9. 【【henuacm2016级暑期训练】动态规划专题 M】Little Pony and Harmony Chest

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每一位显然只要取1..60这些数字. 然后需要保证每个这些数字里面,每个数字所用到的质因子都它所唯一拥有的.别人不能用 因为如果别人 ...

  10. JDBC、事务和连接池

    一:JDBC 1.什么是JDBC JDBC(Java Data Base Connectivity)SUN公司提供的一套操作数据库的标准规范.具体来讲是一种用于执行SQL语句的Java API,为多种 ...