ZOJ 1788 Quad Trees (朴素BFS)

任意门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=788

 

给一个二进制黑白图像,进行压缩.且图像是以2^i 作为边长的正方形

每次对整个图像进行扫描

1.如果全部数据位1 则得到 01

2.如果全部数据位0 则得到 00

3.如果不是上述情况,得到1 并且要对这一部分分解成四个小部分重复上述操作.

将所有得到的数组合起来得到一个二进制数.然后转化为十六进制则为结果 (一种图像压缩方法)

如上图最后得到的数据为 100101100011000000010100010001
再转十六进制 258C0511 

代码有点丑..

#include<iostream>
#include<queue>
#include<algorithm>
#include<string>
#include<vector>
#include<cstdio>
#include<stack>
#include<cmath>
using namespace std;
int data[513][513];
int n;
vector <int>Result;
struct R
{
	int first;
	int end;
};
struct S   //记录搜索范围 
{
	int sx;
	int sy;
	int ex;
	int ey;	
};
void check();   // BFS 搜索 
void BtoHex();  //进制转换 
int main()
{
	int T;
	int i,i2;
	scanf ("%d",&T);
	while (T--)
	{
		Result.clear();
		scanf ("%d",&n);
		for (i=0;i<n;i++)
			for (i2=0;i2<n;i2++)
				scanf ("%d",&data[i][i2]);
		check();
		BtoHex();
 
	}
	return 0;
}
 
 
void check()   //bfs
{
	queue <S> Q;
	S temp;
	int i,i2;
	R temp2;
	temp.sx=0;
	temp.sy=0;
	temp.ex=n-1;
	temp.ey=n-1;
	Q.push(temp);  //first
	while (!Q.empty())
	{
		temp=Q.front();
		Q.pop();
 
		temp2.end=data[temp.sx][temp.sy];
		temp2.first=0;
		if (temp.sx==temp.ex&&temp.sy==temp.ey)  //如果起点和终点一起 
		{
			Result.push_back(0);
			if (data[temp.sx][temp.sy]==0)
				Result.push_back(0);
			else
				Result.push_back(1);
			continue;
		}
		for (i=temp.sx;i<=temp.ex;i++)    //扫描 
			for (i2=temp.sy;i2<=temp.ey;i2++)
				if (temp2.end!=data[i][i2])
				{
					temp2.first=1;
					break;
				}
 
		if (temp2.first==1)    //如果需要深入扫描 
		{
			Result.push_back(1);
			S parts;
			int length=(temp.ex-temp.sx+1)/2;
			if (!(temp.sx==temp.ex&&temp.sy==temp.ey))
			{
				parts.sx=temp.sx;         //分成四个部分 
				parts.sy=temp.sy;
				parts.ex=temp.ex-length;
				parts.ey=temp.ey-length;
				Q.push(parts);
 
				parts.sx=temp.sx;
				parts.sy=temp.sy+length;
				parts.ex=temp.ex-length;
				parts.ey=temp.ey;
				Q.push(parts);
 
				parts.sx=temp.sx+length;
				parts.sy=temp.sy;
				parts.ex=temp.ex;
				parts.ey=temp.ey-length;
				Q.push(parts);	
 
				parts.sx=temp.sx+length;
				parts.sy=temp.sy+length;
				parts.ex=temp.ex;
				parts.ey=temp.ey;
				Q.push(parts);						
			}
		}
		else     //不需要继续深入扫描的情况 
		{
			temp2.first=0;
			Result.push_back(temp2.first);
			Result.push_back(temp2.end);
		}
	}
}
 
void BtoHex()        //二进制转十六进制 
{
	stack <int> s;
	int i=Result.size()-1;
	int sum=0;
	int count=0;
	for (;i>=0;i--)
	{
		sum+=Result[i]*pow(2.0,count);
		if (count==3)
		{
			count=0;
			s.push(sum);
			sum=0;
		}
		else
			count++;
	}
	if (sum!=0)
		s.push(sum);
	if (s.empty())
	{
		printf("0\n");
		return;
	}
	while (!s.empty())
	{
		if (s.top()>=10)
		{
			printf("%c",s.top()+55);
		}
		else
			printf("%d",s.top());
		s.pop();
	}
	printf("\n");
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值