题目链接 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=, int y=):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=, dir[][]={,,,-,,,-,};
  14. int n, h, w, ans[][][]={}, vis[][];
  15. typedef set<Cell> Poly;
  16. set<Poly> state[];
  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=; i<; 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=; i<; 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(, ));
  65. state[].insert(p);
  66.  
  67. for (n=; n<=maxn; n++)
  68. for (set<Poly>::iterator p=state[n-].begin(); p!=state[n-].end(); ++p)
  69. for (Poly::iterator c=(*p).begin(); c!=(*p).end(); ++c)
  70. for (int j=; j<; j++){
  71. Cell nc((c->x)+dir[j][], (c->y)+dir[j][]);
  72. if (!(p->count(nc))) check(*p, nc);
  73. }
  74. for (n=; n<=maxn; n++){
  75. for (set<Poly>::iterator p=state[n].begin(); p!=state[n].end(); ++p){
  76. int maxx=, maxy=;
  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+][maxy+]++;
  82. else ans[n][maxy+][maxx+]++;
  83. }
  84. }
  85. }
  86.  
  87. int show(int w, int h){
  88. int spr=(w>h)?w:h, mnr=(w!=spr)?w:h, re=;
  89. for (int i=; i<=spr; i++)
  90. for (int j=; 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)== && n)
  99. printf("%d\n", (n==)?:show(w, h));
  100.  
  101. return ;
  102. }

因为思路一的代码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. 脑图工具MindNode"附属节点"是什么意思 图解

    新手会发现在主节点上无论是按Tab子节点还是按Enter附属节点,都是向右延伸,感觉像没区别? 其实不然,从第二个节点开始,你再按 Tab 或者 Enter 就知道区别了. 废话少说,直接上图. 我觉 ...

  2. CorelDRAW升级计划--如何购买

    了解通过全新 CorelDRAW 2017升级计划更新此图形设计软件所有最新功能的实惠方案.助升级计划,您可以在下一主要产品版本推出时便收到该版本,从而始终使您的产品保持最新.升级计划取代为 X6 和 ...

  3. ajax中遇到无法发送的问题,以及收不到返回信息的问题

    1.在做ajax时,数据发送成功,后台确认了也返回了信息,但是怎么都在success里面接收不了,我遇见的造成的原因时因为dataType返回值类型错误造成的原因. var url = "请 ...

  4. easyUI datagrid表头的合并

    图列: js代码 function initConfigTable(param){ $("#mulConfigureTableBox").empty(); $("#mul ...

  5. 小程序全局状态管理,在页面中获取globalData和使用globalSetData

    GitHub: https://github.com/WozHuang/mp-extend 主要目标 微信小程序官方没有提供类似vuex.redux全局状态管理的解决方案,但是在一个完整的项目中各组件 ...

  6. qt 摄像头程序

    http://www.oschina.net/code/snippet_124925_3789?p=3#comments http://www.codesoso.net/Search?q=qt+%C9 ...

  7. elasticsearch的安装和使用

    准备环境: 环境: win7 64位  jdk1.8.0  elasticsearch2.3.3 elasticsearch2.3.3:https://www.elastic.co/thank-you ...

  8. Linux学习总结(16)——CentOS 下 Nginx + Tomcat 配置负载均衡

    最近在读埃隆·马斯克传记,他说「我认为现在有非常多的聪明人都在致力于互联网」. 仔细一想,好像真的是这样的. 我问了自己一个问题:如果你不敲代码了,你能做什么? 答案令人极其恐怖.吓得我赶紧又去写了一 ...

  9. 数据结构实现(四)二叉查找树java实现

    转载 http://www.cnblogs.com/CherishFX/p/4625382.html 二叉查找树的定义: 二叉查找树或者是一颗空树,或者是一颗具有以下特性的非空二叉树: 1. 若左子树 ...

  10. maven规定的目录

    Maven规定的目录结构 若要使用Maven,那么项目的目录结构必须符合Maven的规范 ,如写一个使用Spring的Web项目就需要引入大量的jar包.一个项目Jar包的数量之多往往让我们瞠目结舌, ...