任意门: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");
}