zoukankan      html  css  js  c++  java
  • 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
    ",ANS(n,w,h));
        }
        return 0;
    }
  • 相关阅读:
    mv命令(转)
    Linux获得命令帮助(学习笔记五)
    Shell解释器(学习笔记四)
    rmdir 命令(转)
    Java从零开始学十八(抽象类和接口)
    rm 命令(转)
    Centos6.6系统root用户密码恢复案例(转)
    Java从零开始学十七(简单工厂)
    Java从零开始学十六(多态)
    mkdir命令(转)
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4644273.html
Copyright © 2011-2022 走看看