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

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

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

#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;

}

 

你可能感兴趣的:(STL)