zoukankan      html  css  js  c++  java
  • UVA-1602 Lattice Animals 搜索问题(打表+set)

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

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

  • 相关阅读:
    Maven pom.xml中添加指定的中央仓库
    命令行远程链接MySQL
    A required class was missing while executing org.apache.maven.plugins:maven-war-plugin:2.1.1:war
    mvn deploy命令上传包
    保存好你的密码
    PuTTY免输密码自动登录Linux
    ActiveMQ无法启动
    linux控制台批量杀进程
    dubbo入门之微服务客户端服务端配置
    dubbo入门之helloWorld
  • 原文地址:https://www.cnblogs.com/tanglizi/p/7523898.html
Copyright © 2011-2022 走看看