您的位置:首页 > 其它

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

2015-07-13 23:53 477 查看
多联骨牌的生成办法,维基上只找到固定的骨牌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
.count(p)) return;
Rotate(p);
}
flip(p);
for(int i = 0; i < 4; i++){
if(poly
.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
= 0;
for(set<Polyomino>::iterator it = poly
.begin(); it != poly
.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
[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
[w][h]){
V
[SIZE
++] = whc(w,h,mp
[w][h]);
}
}
}

}

inline int ANS(int n,int w,int h){
if(~ans
[w][h]) return ans
[w][h];
else {
int cnt = 0;
whc *a = V
;
for(int i = 0, sz =SIZE
; i < sz; i++ ){
whc & u = a[i];
if(u.w < w && u.h < h) cnt += u.c;
}
return ans
[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: