实现的细节很多,学到了如何翻转、旋转、平移,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. linux_定时任务

    什么是定时任务? linux系统自身定期执行的任务和工作: 轮训系统日志.备份系统数据.清理缓存等 var/log/messages # 系统日志文件, ll /etc/|grep cron # 查询 ...

  2. Java常用类--数字常用类

    math java提供了基本的 + - * / %等基本算术运算的运算符,但对于更复杂的数学运算比如:三角函数,对数运算,指数运算就无能为力了.Java提供了Math工具类来完成这些复杂的运算,Mat ...

  3. Python笔记(七):字典、类、属性、对象实例、继承

    (一)  简单说明 字典是Python的内置数据结构,将数据与键关联(例如:姓名:张三,姓名是键,张三就是数据).例如:下面这个就是一个字典 {'姓名': '张三', '出生日期': '2899-08 ...

  4. Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】

    什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录 ...

  5. 09_Python深拷贝、浅拷贝

    一.循环列表,删除其中的元素 l1 = [1,2,3,4,5,6,7]  循环删除奇数位元素 1.正序循环删除,会出现越界情况,所以采用倒叙的方式删除 l1 = [1,2,3,4,5,6,7] for ...

  6. MongoDB入门系列(三):查询(SELECT)

    一.概述 mongodb是最接近关系型数据库的NOSQL数据库,它的存储方式非常的灵活:以至于你会将它看成是一个经过冗余过的关系型数据库的表,这也是Mongodb原子性的一个特征.由于没有关系型数据库 ...

  7. phpstorm中使用xdebug配置cli模式的调试

    这里略去xdebug的安装,安装很简单可以下载源码包,动态编译进去! 环境: Dev 服务器(IP:192.168.2.100),安装phpstorm,用来做开发任务! Server服务器(IP:19 ...

  8. Java内存回收机制基础[转]

    原文链接:http://blog.jobbole.com/37273/ 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了J ...

  9. Python tutorial阅读之函数的定义与使用

    函数的定义 Python 使用关键字def定义函数,格式与C语言类似,但是没有返回类型,参数也不需要设置类型. def add(a, b): """这是函数的文档字符串& ...

  10. Go经验总结----2017.07

    1. 自定义返回一个错误信息:return errors.New("invalid action") 2.golang这种所有被大括号包裹起来的语句都不能在外面被调用.例如:if ...