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

多联骨牌的生成办法,维基上只找到固定的骨牌fix,而free的没有找到。

于是只好写个set判重的简单枚举了。

旋转的操作,可以在坐标轴上画个点,以原点为轴心,逆时针旋转90度,新的点的坐标为(-y,x)。顺时针也差不多。

反转类似。

对于操作完的骨牌,还要进行标准化,取最小的横纵坐标为参考,求出新的坐标,以便于判断。

生成所有骨牌以后,预处理一下(一顿乱搞)就好了。

 

#include<bits/stdc++.h>
using namespace std;

#define local

const int maxn = 11;

struct Cell
{
    int x,y;
    Cell(int x = 0,int y = 0):x(x),y(y){}
    bool operator < (const Cell & rhs) const {
        return x < rhs.x||(x == rhs.x && y < rhs.y);
    }
};
#define FOR_CELL(c, p) for(Polyomino::const_iterator c = (p).begin(); c != (p).end(); ++c)

typedef set<Cell> Polyomino;

inline void normalize(Polyomino *px){
    int minx = px->begin()->x, miny = px->begin()->y;
    Polyomino::const_iterator c;
    for(c = px->begin(); c != px->end(); ++c) {
        minx = min(minx, c->x);
        miny = min(miny, c->y);
    }
    Polyomino pn;
    for(c = px->begin(); c != px->end(); ++c){
        pn.insert(Cell(c->x-minx,c->y-miny));
    }
    *px = pn;
}

inline void Rotate(Polyomino & px) {
    Polyomino p2;
    Polyomino::const_iterator c;
    for(c = px.begin(); c != px.end(); ++c)
        p2.insert(Cell(c->y,-c->x));
    px = p2;
    normalize(&px);
}

inline void flip(Polyomino &px) {
    Polyomino p3;
    Polyomino::const_iterator c;
    for(c = px.begin(); c != px.end(); ++c)
        p3.insert(Cell(-c->x,c->y));
    normalize(&p3);
    px = p3;
}

set<Polyomino>poly[maxn];


void check(const Polyomino &p0,Cell& newCell){
    Polyomino p = p0;
    p.insert(newCell);
    normalize(&p);
    int n = p.size();
    for(int i = 0; i < 4; i++){
        if(poly[n].count(p)) return;
        Rotate(p);
    }
    flip(p);
    for(int i = 0; i < 4; i++){
        if(poly[n].count(p)) return;
       Rotate(p);
    }
    poly[p.size()].insert(p);
}

int ans[maxn][maxn][maxn];

struct whc
{
    int w,h,c;
    whc(){}
    whc(int w,int h,int c):w(w),h(h),c(c){}
};

int SIZE[maxn] = {0};
whc V[maxn][17];

void generatePoly(){
    const int dx[] = {0,0,1,-1};
    const int dy[] = {1,-1,0,0};
    Polyomino s;
    s.insert(Cell(0,0));
    poly[1].insert(s);

    for(int i = 1; i < maxn-1; i++){
        for(set<Polyomino>::iterator it = poly[i].begin(); it != poly[i].end(); it++ ){
            FOR_CELL(c,*it){
                for(int dir = 0; dir < 4; dir++){
                    Cell newc(c->x+dx[dir],c->y+dy[dir]);
                    if(it->count(newc) == 0) check(*it,newc);
                }
            }
        }
    }



    int mp[maxn][maxn][maxn] = {0};
    for(int n = 1; n < maxn; n++){
        SIZE[n] = 0;
        for(set<Polyomino>::iterator it = poly[n].begin(); it != poly[n].end(); it++ ){
            int maxx,maxy; maxx = maxy = 0;
            FOR_CELL(c,*it){
                maxx = max(maxx,c->x);
                maxy = max(maxy,c->y);
            }
            if(maxy<maxx) swap(maxx,maxy);
            mp[n][maxx][maxy]++;
        }
    }

     for(int n = 1; n < maxn; n++){
        for(int w = 0; w < n; w++)
        for(int h = w; h < n; h++){
            if(mp[n][w][h]){
                V[n][SIZE[n]++] = whc(w,h,mp[n][w][h]);
            }
        }
     }



}

inline int ANS(int n,int w,int h){
    if(~ans[n][w][h]) return ans[n][w][h];
    else {
        int cnt = 0;
        whc *a = V[n];
        for(int i = 0, sz =SIZE[n] ; i < sz; i++ ){
            whc & u = a[i];
            if(u.w < w && u.h < h) cnt += u.c;
        }
        return ans[n][w][h] = cnt;
    }
}

int main()
{
#ifdef local
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
#endif // local
    generatePoly();
    memset(ans,-1,sizeof(ans));
    int n,w,h;
    while(~scanf("%d%d%d",&n,&w,&h)){
        if(h<w) swap(w,h);
        printf("%d\n",ANS(n,w,h));
    }
    return 0;
}

 

posted @ 2015-07-13 23:53  陈瑞宇  阅读(530)  评论(0编辑  收藏  举报