BNUOJ-4049-四叉树

四叉树
Time Limit: 1000msMemory Limit: 65536KB 64-bit integer IO format: %lld Java class name: Main
Prev Submit Status Statistics Discuss Next
Type:
None

Tag it!
四叉树是一种常用的数据结构,广泛应用于栅格数据(如地图数据、遥感图像)的压缩编码中。将四叉树扩展到三维就形成了八叉树,可实现三维信息的压缩存储。下面是它的实现原理:
这里写图片描述

如图是一个8*8图象,如果该图像所有元素都一样(都是0或都是1),就编码为0,再加上公共一样的元素(如01或00)。如果不一样,就先编码为1,然后把图像分成4个4*4图像。继续上面的操作,直到该小区域中,所有像素都是一样的元素为止(当然,最后可能只剩下一个象素点)。最后,(如(d)图)按照剖分的层次,自顶向下,从左至右,把所有的01序列连接起来。如上图,图像的编码为:100101100011000000010100010001 注意:同一层次四个小图象,合并的顺序是:左上、右上、左下,右下,如(d)图所示。
本题要求同学们编程实现这一编码过程,输出压缩之后的0-1序列。

Input
输入第一行,一个正整数n,一定是2的幂(2、4、8、16等等),最大不超过16
下面是一个n*n的01矩阵,矩阵的元素只有0和1

Output
输出压缩之后的01序列,一个字符串,只有0和1

Sample Input
8
0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0
1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

Sample Output
100101100011000000010100010001
Source
中国地质大学(北京)第三届程序设计竞赛

可以选择建立四叉树,然后进行维护。也可以用深搜的方法。
深搜 短短五十多行

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<string.h>
#include<ctype.h>
using namespace std;
const int maxn=18;
int map[maxn][maxn];
string str[maxn];
int n;
bool check(int x,int y,int flag)
{
    for(int i=0; i<flag; ++i)
        for(int j=0; j<flag; ++j)
            if(map[x+i][y+j]!=map[x][y])
                return false;
    return true;
}
void DFS(int x,int y,int flag,int deep)//搜索起始点坐标,坐标分割次数,递归深度
{
    string temp="1";
    if(check(x,y,flag))
    {
        temp="0";
        if(map[x][y]==0)
            temp+="0";
        else
            temp+="1";
        str[deep]+=temp;
        return;
    }
    str[deep]+=temp;
    DFS(x,y,flag>>1,deep+1);
    DFS(x,y+(flag>>1),flag>>1,deep+1);
    DFS(x+(flag>>1),y,flag>>1,deep+1);
    DFS(x+(flag>>1),y+(flag>>1),flag>>1,deep+1);
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; ++i)
            for(int j=0; j<n; ++j)
                scanf("%d",&map[i][j]);
        for(int i=0; i<maxn; ++i)
            str[i]="";
        DFS(0,0,n,0);
        for(int i=0; i<=log2(n); ++i)
            cout<<str[i];
        cout<<endl;
    }
    return 0;
}

建树 http://blog.csdn.net/wr_technology/article/details/51204075

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值