Poj2266/Poj2270(四元树)

题目链接:http://poj.org/problem?id=2266 

                     http://poj.org/problem?id=2270

 

题意:题目中讲到一种图XBM 的编码方案,从整体到局部的划分图的区域,相同顔色的区域同一块区域可用四元树中的一个节点来覆盖表示。

编码时可构建树后,从叶节点向上进行合并,把相同表示的区域合成一个节点表示,而解码时则可使用递归,分别对是否该节点覆盖了此节点所表示的区域分来进行递

 

归。

2266代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define M 1024

unsigned char map[M][M>>3];

void Run(int t,int l,int s)
{
	int i,j,m;

	switch(getchar()){
	case 'W':
		for(i=t;i<t+s;i++){
			for(j=l;j<l+s;j++){
				map[i][j>>3] &= ~(1<<(j&7));
			}
		}break;
	case 'B':
		for(i=t;i<t+s;i++){
			for(j=l;j<l+s;j++){
				map[i][j>>3] |= (1<<(j&7));
			}
		}break;
	case 'Q':
		m=s>>1;
		Run(t,l,m);
		Run(t,l+m,m);
		Run(t+m,l,m);
		Run(t+m,l+m,m);
	}
}

int main()
{
	int n,i,j;

	scanf("%d ",&n);

	Run(0,0,n);

	printf("#define quadtree_width %d\n",n);
	printf("#define quadtree_height %d\n",n);
	puts("static char quadtree_bits[] = {");

	for(i=0;i<n;i++){
		for(j=0;j<n>>3;j++)
			printf("0x%02x,",map[i][j]);
		puts("");
	}

	puts("};");
	return 0;
}


2270代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>

#define LT(x) ((x<<2)|1)
#define RT(x) ((x<<2)|2)
#define LB(x) ((x<<2)|3)
#define RB(x) ((x<<2)+4)


#define M 1024


typedef struct{
	char c;
	int lt,rt,lb,rb;
}TN;

TN T[M*M];

unsigned char map[M][M>>3];

char tmp[M];

void Create(int ix,int t,int l,int s)
{
	int m;
	if(s==1)
		T[ix].c=map[t][l>>3]&(1<<(l&7))?'B':'W';
	else{
		m=s>>1;
		Create(LT(ix),t,l,m);
		Create(RT(ix),t,l+m,m);
		Create(LB(ix),t+m,l,m);
		Create(RB(ix),t+m,l+m,m);
		if(T[LT(ix)].c==T[RT(ix)].c&&T[LT(ix)].c==T[LB(ix)].c
			&&T[LT(ix)].c==T[RB(ix)].c)
			T[ix].c=T[LT(ix)].c;
		else T[ix].c='Q';
	}
}

void Traverse(int ix)
{
	putchar(T[ix].c);
	if(T[ix].c=='Q'){
		Traverse(LT(ix));
		Traverse(RT(ix));
		Traverse(LB(ix));
		Traverse(RB(ix));
	}
}

int main()
{
	int n,i,j;
		
	scanf("%s%s%d ",tmp,tmp,&n);
	gets(tmp);
	gets(tmp);
	for(i=0;i<n;i++){
		for(j=0;j<n>>3;j++){
			scanf("%x,",&map[i][j]);
		}
	}
	Create(0,0,0,n);
	printf("%d\n",n);
	Traverse(0);
	puts("");
	return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值