zoj1788-Quad Trees

#include<iostream>
#include<string>
#include<queue>
#include<math.h>
using namespace std;
const int maxsize=512;
char MAP[maxsize][maxsize];
struct quadtree
{
	quadtree *q[4];
	string value;
	bool operator == (quadtree temp)
	{
		return temp.value==value;
	}
	quadtree()
	{
		for(int i=0;i<4;i++)
			q[i]=NULL;
	}
};
string levelorder(quadtree *&root)
{
	queue<quadtree > que;
	quadtree temp;
	int i;
	string str;
	que.push(*root);
	while(!que.empty())
	{
		temp=que.front();
		que.pop();
		str+=temp.value;
		for(i=0;i<4;++i)
			if(temp.q[i])
				que.push(*temp.q[i]);
	}
	return str;
}
int turn(const string str)
{
	int i,sum=0;
	for(i=0;i<str.size();++i)
	{
		if(str[str.size()-i-1]=='1')
			sum+=pow(2.0,i);
	}
	return sum;
}
quadtree *DFS(int r,int c,int s)//行号列号间隔
{
	int i;
	bool f=true;
	quadtree *temp=new quadtree;
	if(s==1)//最小格就赋值
	{
		temp->value='0';
		temp->value+=MAP[r][c];
		return temp;
	}
	s/=2;
	temp->q[0]=DFS(r,c,s);//跳格继续递归
	temp->q[1]=DFS(r,c+s,s);
	temp->q[2]=DFS(r+s,c,s);
	temp->q[3]=DFS(r+s,c+s,s);
	for(i=1;i<4;++i)//检测是否需要合并
	{
		if(!(*temp->q[0]==*temp->q[i])||temp->q[0]->value=="1")//不用合并
		{
			f=false;
			break;
		}
	}
	if(f)//需要
	{
		temp->value=temp->q[0]->value;
		for(i=0;i<4;++i)
		{
			delete temp->q[i];
			temp->q[i]=NULL;//防止野指针
		}
	}
	else
		temp->value="1";
	return temp;
}
void deltree(quadtree *&node)//回收内存
{
	if(node)
	{
		for(int i=0;i<4;++i)
		{
			deltree(node->q[i]);
		}
		 delete node;
	}
}
int main()
{
	int icase,i,j,N;
	quadtree *order;
	cin>>icase;
	while(icase--)
	{
		cin>>N;
		for(i=0;i<N;++i)
			for(j=0;j<N;++j)
				cin>>MAP[i][j];
		order=DFS(0,0,N);
		cout.setf(ios_base::hex,ios_base::basefield);//十六进制显示
		cout.setf(ios::uppercase);//大写显示
		cout<<turn(levelorder(order))<<endl;
		deltree(order);
	}
	return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值