zoj 1788 Quad Trees

题意:对于一个0,1矩阵,如果该矩阵全都是一种颜色,那么就在树上表示为(0,1)or(0,0)第二个值看对应区域的颜色是0还是1了,如果颜色不同就在树上标记为1,并且继续细分直到该区域颜色全都相同为止,分法就是把当前区域平均分成4份,如图所示。

求,对于的树的从上倒下,把数据写成一排,如题目图的树,每层分别为,1,001011,000110000000101,00010001,连接在一块就成了一个二进制数,100101100011000000010100010001,把这个二进制数以16进制输出

bfs求解

#include <bits/stdc++.h>
using namespace std;
#define maxn 520
struct node
{
	int x,y;
	int len;
};
int d[maxn][maxn];
queue<int> dd;
queue<node> qq;
int mapp[maxn][maxn][10];
int check(int x,int y,int len)
{
	if (len==1){
		mapp[x][y][1]=0;
		return d[x][y];
	}
	int a1,a2,a3,a4;
	a1=check(x,y,len/2);
	a2=check(x,y+len/2,len/2);
	a3=check(x+len/2,y,len/2);
	a4=check(x+len/2,y+len/2,len/2);
	if (a1!=2&&a1==a2&&a1==a3&&a1==a4){
		mapp[x][y][len]=0;
		return d[x][y];
	}
	mapp[x][y][len]=1;
	return 2;
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int kk;scanf("%d",&kk);
	while(kk--){
		int n;scanf("%d",&n);
		for (int i=1;i<=n;i++){
			for (int j=1;j<=n;j++){
				scanf("%d",&d[i][j]);
			}
		}

        check(1,1,n);

		if (mapp[1][1][n]){
			node as;
			as.x=1;as.y=1;as.len=n;
			qq.push(as);
			dd.push(1);
		}

		while(!qq.empty()){
			node as=qq.front();
			qq.pop();
			node a1,a2,a3,a4;
			a1.x=as.x;a1.y=as.y;a1.len=as.len/2;
			a2.x=as.x;a2.y=as.y+as.len/2;a2.len=as.len/2;
			a3.x=as.x+as.len/2;a3.y=as.y;a3.len=as.len/2;
			a4.x=as.x+as.len/2;a4.y=as.y+as.len/2;a4.len=as.len/2;
			int d1,d2,d3,d4;
			d1=mapp[a1.x][a1.y][a1.len];
			d2=mapp[a2.x][a2.y][a2.len];
			d3=mapp[a3.x][a3.y][a3.len];
			d4=mapp[a4.x][a4.y][a4.len];
			if (d1){
				qq.push(a1);
				dd.push(1);
			}
			else
			{
				dd.push(0);
				dd.push(d[a1.x][a1.y]);
			}
			if (d2){
				qq.push(a2);
				dd.push(1);
			}
			else
			{
				dd.push(0);
				dd.push(d[a2.x][a2.y]);
			}
			if (d3){
				qq.push(a3);
				dd.push(1);
			}
			else
			{
				dd.push(0);
				dd.push(d[a3.x][a3.y]);
			}
			if (d4){
				qq.push(a4);
				dd.push(1);
			}
			else
			{
				dd.push(0);
				dd.push(d[a4.x][a4.y]);
			}
		}

		int sum=0;
		while(!dd.empty()){
			sum=sum*2+dd.front();
			dd.pop();
		}

		stack<char> ans;

		if (sum==0){
            ans.push('0');
        }

		while(sum>0){
			int data=sum%16;
			if (data<10){
				ans.push(data+'0');
			} else ans.push(data-10+'A');
			sum=sum/16;
		}




		while(!ans.empty()){
			printf("%c",ans.top());
			ans.pop();
		}
		printf("\n");

	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值