uva 1602 Lattice Animals

题目:Lattice Animals


思路:

dfs。

搜索时,每一次都在上一次的图形上加一个方块,具体方法是遍历上一次的图形,在每一个方块的上下左右都尝试放一个方块。

每次搜得一个图形,就将它化为一个标准型式,即整个图形都在第一象限且过原点。然后将这个新的图形翻折、旋转,并把这些变形存进一个set里便于判重。


注意:

只需搜索一次,处理出所有权情况并打表,这可以节省不少时间。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<sstream>
#include<queue>
#include<set>
using namespace std;

#define maxn 10

struct Node {
	int x,y;
	Node() {
		x=0,y=0;
	}
	Node(int one,int two) {
		x=one,y=two;
	}
	bool operator < (const Node& other) const {
		if(x<other.x||(x==other.x&&y<other.y)) return true;
		return false;
	}
	Node Place(int a,int b) {
		return Node(x+a,y+b);
	}
};

struct Block {
	set<Node> Set;
	void insert(Node y) {
		Set.insert(y);
	}
	bool operator < (const Block& other) const {
		if(Set.size()<other.Set.size()) return true;
		if(Set.size()>other.Set.size()) return false;
		vector<Node> one,two;
		for(set<Node>::iterator it=Set.begin(); it!=Set.end(); it++) {
			one.push_back(*it);
		}
		for(set<Node>::iterator it=other.Set.begin(); it!=other.Set.end(); it++) {
			two.push_back(*it);
		}
		for(int i=0; i<one.size(); i++) {
			if(one[i]<two[i]) return true;
			if(two[i]<one[i]) return false;
		}
		return false;
	}
};

set<Block> Use;

int f[maxn+5][maxn+5][maxn+5]= {0};

Block ToStd(Block x) {
	int minx=maxn+5,miny=maxn+5;
	for(set<Node>::iterator it=x.Set.begin(); it!=x.Set.end(); it++) {
		Node y=(*it);
		minx=min(minx,y.x);
		miny=min(miny,y.y);
	}
	Block Standard;
	for(set<Node>::iterator it=x.Set.begin(); it!=x.Set.end(); it++) {
		Node y=(*it);
		y.x-=minx;
		y.y-=miny;
		Standard.Set.insert(y);
	}
	return Standard;
}

Block miro(Block x) {
	Block Standard;
	for(set<Node>::iterator it=x.Set.begin(); it!=x.Set.end(); it++) {
		Node y=(*it);
		y.y=0-y.y;
		Standard.Set.insert(y);
	}
	return ToStd(Standard);
}

Block Turn(Block x) {
	Block Standard;
	for(set<Node>::iterator it=x.Set.begin(); it!=x.Set.end(); it++) {
		Node y=(*it);
		int t=y.x;
		y.x=y.y;
		y.y=0-t;
		Standard.Set.insert(y);
	}
	return ToStd(Standard);
}

Node Measure(Block x) {
	int maxX=0,maxY=0;
	for(set<Node>::iterator it=x.Set.begin(); it!=x.Set.end(); it++) {
		Node y=(*it);
		maxX=max(maxX,y.x);
		maxY=max(maxY,y.y);
	}
	return Node(maxX+1,maxY+1);
}

void make(int step,Block x) {
	if(step>maxn) return ;
	Block y=x;
	if(Use.find(y)!=Use.end()) return ;
	for(int i=1; i<=4; i++) {
		y=Turn(y);
		Use.insert(y);
	}
	y=miro(y);
	for(int i=1; i<=4; i++) {
		y=Turn(y);
		Use.insert(y);
	}
	Node m=Measure(y);
	bool a[maxn+5][maxn+5]={0};
	for(int i=m.x;i<=maxn;i++){
		for(int j=m.y;j<=maxn;j++){
			a[i][j]=a[j][i]=true;
		}
	}
	for(int i=1;i<=maxn;i++){
		for(int j=1;j<=maxn;j++){
			f[step][i][j]+=a[i][j];
		}
	}

	int M1[5]= {0,1,-1,0,0};
	int M2[5]= {0,0,0,1,-1};
	for(set<Node>::iterator it=x.Set.begin(); it!=x.Set.end(); it++) {
		Node y=(*it);
		for(int i=1; i<=4; i++) {
			Block New=x;
			New.insert(y.Place(M1[i],M2[i]));
			if(New.Set.size()!=x.Set.size()) {
				New=ToStd(New);
				make(step+1,New);
			}
		}
	}

}

void init() {
	Use.clear();
}

int main() {
	init();
	Block x;
	x.insert(Node());
	make(1,x);

	int n,w,h;
	while(~scanf("%d%d%d",&n,&w,&h)) {
		printf("%d\n",f[n][w][h]);
	}

	return 0;
}



  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值