UVA - 1602(Polyomino的存储和判重)

来源:互联网 发布:ui美工培训 编辑:程序博客网 时间:2024/06/05 00:15
#include <set>#include <cstdio>#include <cstring>#include <iostream>using namespace std;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;}};typedef set<Cell> Polyomino; //存图方法#define rep(c,p) for(Polyomino::const_iterator c =(p).begin();c!=(p).end();c++)inline Polyomino normalize(const Polyomino& s){ //将任意坐标图标准化,即最小x,最小y都化为一int sx = s.begin()->x,sy = s.begin()->y;rep(c,s){sx = min(c->x,sx);sy = min(c->y,sy);}Polyomino p;rep(c,s){p.insert( Cell(c->x - sx, c->y - sy) );}return p;}inline Polyomino flip(const Polyomino& s){ //左右翻转图,先对称,后标准化Polyomino p;rep(c,s){p.insert(Cell(c->x,-c->y));}return normalize(p);}inline Polyomino rotate(const Polyomino& s){ //(x,y) -->(y,-x) --> (-x,-y) --> (-y,x) --> (x,y); 分别对应原图旋转k*90度时候的状态 Polyomino p;rep(c,s){p.insert(Cell(c->y,-c->x));}return normalize(p);}const int maxn = 10;const int dx[]={1,0,-1,0};const int dy[]={0,-1,0,1};int d[maxn+1][maxn+1][maxn+1]={0};set<Polyomino> plan[maxn+1];inline void check_polyomino(const Polyomino& s,const Cell& t,int n){ //每个连通最最多有八种形态,都需判断;Polyomino p = s;p.insert(t);p = normalize(p);if(p.size()<n) return ;for(int i=0;i<4;i++){     p = rotate(p);     if(plan[n].count(p)) return;}p = flip(p);for(int i=0;i<4;i++){     p = rotate(p);     if(plan[n].count(p)) return;}plan[n].insert(p);}void solve(){Polyomino p;p.insert(Cell(0,0));plan[1].insert(p);//generate all the polyominofor(int n=2;n<=10;n++){     for(set<Polyomino>::iterator i=plan[n-1].begin();i!=plan[n-1].end();i++){          rep(c,*i){              for(int d=0;d<4;d++){                 int nx = dx[d] + (c->x),ny = dy[d] + (c->y);                  if(!i->count(Cell(nx,ny))) check_polyomino(*i,Cell(nx,ny),n);              }          }     }}for(int i=1;i<=maxn;i++)    for(int j=1;j<=maxn;j++)       for(int k=1;k<=maxn;k++){          int cnt=0;          for(set<Polyomino>::iterator g=plan[i].begin();g!=plan[i].end();g++){             bool flag =true;             int mx=0,my=0;             rep(c,*g){             mx=max(mx,c->x);             my=max(my,c->y);             }             if(min(mx,my) < min(j,k) && max(mx,my) < max(j,k)) cnt++;          }          d[i][j][k] = cnt;}}int main(){    solve();    int k,n,m;    while(scanf("%d %d %d",&k,&n,&m)==3){          printf("%d\n",d[k][n][m]);    }    return 0;}

0 0
原创粉丝点击