现在的位置: 首页 > 综合 > 正文

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

2019年04月03日 ⁄ 综合 ⁄ 共 1914字 ⁄ 字号 评论关闭
#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 polyomino
for(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;
}

抱歉!评论已关闭.