实现的细节很多,学到了如何翻转、旋转、平移,get很多技巧,值得一做。

AC代码:

#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=10+5;
int ans[maxn][maxn][maxn];

struct animal{
    int x,y;
    animal(int x=0,int y=0):x(x),y(y){};
    bool operator < (const animal &p) const {
        return x<p.x||(x==p.x&&y<p.y);
    }
};
typedef set<animal> node;
#define For_animal(c,p) for(node::iterator c=(p).begin();c!=(p).end();++c)

inline node normalize(const node &p){  //normalize
    int minx=p.begin()->x,miny=p.begin()->y;
    For_animal(c,p){
        minx=min(minx,c->x);
        miny=min(miny,c->y);
    }
    node p2;
    For_animal(c,p){
        p2.insert(animal(c->x-minx,c->y-miny));
    }
    return p2;
}

inline node rotate(const node &p){  //rotate
    node p2;
    For_animal(c,p){
        p2.insert(animal(c->y,-c->x));
    }
    return normalize(p2);
}

inline node flip(const node &p){ //flip
    node p2;
    For_animal(c,p){
        p2.insert(animal(c->x,-c->y));
    }
    return normalize(p2);
}

const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
set<node>poly[maxn];

void add(const node &p0,const animal &newc){ //add
    node p=p0;
    p.insert(newc);
    p=normalize(p);
    int n=p.size();
    for(int i=0;i<4;++i){
        if(poly[n].count(p)!=0) return;
        p=rotate(p);
    }
    p=flip(p);
    for(int i=0;i<4;++i){
        if(poly[n].count(p)!=0) return;
        p=rotate(p);
    }
    poly[n].insert(p);
}

void solve(){
    node s;
    s.insert(animal(0,0));
    poly[1].insert(s);

    for(int n=2;n<=10;++n){
        for(set<node>::iterator p=poly[n-1].begin();p!=poly[n-1].end();++p){
           For_animal(c,*p)     //从当前联通块开始延伸
                for(int dir=0;dir<4;++dir){
                    int newx=c->x+dx[dir],newy=c->y+dy[dir];
                    animal newc(newx,newy);
                    if(p->count(newc)==0) add(*p,newc);
                }
        }
    }

    //make answer into array
    const int len=10;
    for(int n=1;n<=len;++n)
        for(int w=1;w<=len;++w)
            for(int h=1;h<=len;++h){
                int cnt=0;
                for(set<node>::iterator p=poly[n].begin();p!=poly[n].end();++p){
                    int maxx=0,maxy=0;
                    For_animal(c,*p){
                        maxx=max(maxx,c->x);
                        maxy=max(maxy,c->y);
                    }
                    if(min(maxx,maxy)<min(w,h)&&max(maxx,maxy)<max(w,h))  //这个地方是<而不是<=的原因是坐标是从0开始
                        ++cnt;
                }
                ans[n][w][h]=cnt;
            }

}

int main(){
    solve();
    int n,w,h;
    while(scanf("%d%d%d",&n,&w,&h)==3){
        printf("%d\n",ans[n][w][h]);
    }
    return 0;
}

如有不当之处欢迎指出!

UVA1602的更多相关文章

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

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

  2. UVA1602 Lattice Animals 网格动物 (暴力,STL)

    多联骨牌的生成办法,维基上只找到固定的骨牌fix,而free的没有找到. 于是只好写个set判重的简单枚举了. 旋转的操作,可以在坐标轴上画个点,以原点为轴心,逆时针旋转90度,新的点的坐标为(-y, ...

  3. UVA1602 Lattice Animals 搜索+剪枝

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

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

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

  5. 网格动物UVA1602

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

  6. UVa 1602 网格动物(回溯)

    https://vjudge.net/problem/UVA-1602 题意:计算n连通块不同形态的个数. 思路: 实在是不知道该怎么做好,感觉判重实在是太麻烦了. 判重就是判断所有格子位置是否都相同 ...

随机推荐

  1. JDK自带的日志Logging

    OK,现在我们来研究下JDK自带的日志Logger. 从jdk1.4起,JDK开始自带一套日志系统.JDK Logger最大的优点就是不需要任何类库的支持,只要有Java的运行环境就可以使用. 相对于 ...

  2. Linxu指令--date,cal

    在linux环境中,不管是编程还是其他维护,时间是必不可少的,也经常会用到时间的运算,熟练运用date命令来表示自己想要表示的时间,肯定可以给自己的工作带来诸多方便. 1.命令格式: date [参数 ...

  3. linkin大话数据结构--Map

    Map 映射关系,也有人称为字典,Map集合里存在两组值,一组是key,一组是value.Map里的key不允许重复.通过key总能找到唯一的value与之对应.Map里的key集存储方式和对应的Se ...

  4. 在vue中优雅地实现简单页面逆传值

    [需求] 要实现的需求很简单,页面从A -> B,用户在B触发操作,将一些数据带回到A页面,在网上找了好久也只看到有人问,但总找不到很好答案.要实现的效果图如下: [联想] 在 ios 开发中, ...

  5. RChain总体架构图

    RChain是我研究区块链依赖发现的和我最契合的(主要是用scala写的),在架构上吞吐率和扩展性也是最好,未来是真正有可能实现在它官网上宣称的能够承载facebook一样的规模,具有和visa一样的 ...

  6. 提取位于<title>...</title>内的文本标题内容

    #vim title.txt <title>nhlinkin</title> # cat title.txt  | sed 's:.*<title>\([^< ...

  7. MonogoDB 查询小结

    MonogoDB是一种NoSQL数据库 优点: 1.数据的存储以json的文档进行存储(面向文档存储) 2.聚合框架查询速度快 3.高效存储二进制大对象 缺点: 1.不支持事务 2.文件存储空间占用过 ...

  8. 从源码安装go 1.2.2

    获取代码 以下命令会创建一个go目录.切换到相应目录,并且确保当前位置不存在go目录,运行命令: hg clone -r release https://go.googlecode.com/hg/ g ...

  9. “字符串替换” 和 “模板设置” (application/config.php)

    //视图输出字符串内容替换'view_replace_str' => [ '__PUBLIC__' => '/public/', '__ROOT__' => '/',], 模板设置: ...

  10. linux 基础信息查询

    Linux下如何查看版本信息   Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然.   1.# uname -a   (Linux查看 ...