题意:黑白图像有两种表示法:点阵表示和路径表示。 路径表示法首先需要把图像转化为四分树,然后记录所有黑结点到根的路径。 将俩种表示法之间进行交换。结点是由路径构成的五进制再转换成十进制的值。NW、 NE、 SW、 SE分别用1、 2、 3、 4表示。
思路:因为是四分树,一个矩阵横纵平分即为四分,所以不断的平分矩阵建树。
1.点阵转换路径:
dfs1(int r,int c,int w,double res,int floor){//将图转化为结点:r:左上角横坐标,c:左上角纵坐标,w:矩阵大小,res:计算结点的值,floor:层数
不断的递归寻找,每次递归顺便在递归式中直接将五进制计算为十进制;直到寻找到当前的矩阵全部为1即为结点,将其保存。
每次平分矩阵时有四个,将平分的矩阵的左上角的横纵坐标传入。
最后将结点排序,按每行最多12个输出即可。
2.路径转换点阵:
dfs2(int r,int c,int w,int floor){//将结点转化为图:r:矩阵左上角横坐标,c:矩阵左上角纵坐标,floor:层数
将每个结点转换成五进制,五进制的值即为路径,根据五进制递归,直到达叶子结点即五进制值的最后一个值,将其所在的矩阵染成*即可。
注意:输入输出格式是:先输入个数,然后换行(第一次不换),然后输出Image ,然后输入案例,最后输出结果。
代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 70;
char marix[maxn][maxn];
vector<double>node;
void dfs1(int r,int c,int w,double res,int floor){//将图转化为结点:r:左上角横坐标,c:左上角纵坐标,w:矩阵大小,res:计算结点的值,floor:层数
int cot = 0;
for(int i=r;i<r+w;i++){//计算当前矩阵中的面积即1的个数
for(int j=c;j<c+w;j++){
if(marix[i][j] == '1') cot++;
}
}
if(cot == 0) return;//当1的个数为0说明为空结点
else if(cot == w*w){//当当前矩阵全部为1说明是结点
node.push_back(res);//将结点保存
}
else{
dfs1(r ,c ,w/2,res+1*pow(5,floor),floor+1);//上左
dfs1(r ,c+w/2,w/2,res+2*pow(5,floor),floor+1);//上右
dfs1(r+w/2,c ,w/2,res+3*pow(5,floor),floor+1);//下左
dfs1(r+w/2,c+w/2,w/2,res+4*pow(5,floor),floor+1);//下右
}
}
int len,tran[maxn];
int translate(long long v,int tra[]){//五进制转换
int i=0;
while(v){
tra[i++] = v%5;
v/=5;
}
return i;}
void dfs2(int r,int c,int w,int floor){//将结点转化为图:r:矩阵左上角横坐标,c:矩阵左上角纵坐标,floor:层数
if(floor == len){
for(int i=r;i<r+w;i++){
for(int j=c;j<c+w;j++)
marix[i][j] = '*';
}
return;
}
if(tran[floor] == 1) dfs2(r ,c ,w/2,floor+1);//上左
if(tran[floor] == 2) dfs2(r ,c+w/2,w/2,floor+1);//上右
if(tran[floor] == 3) dfs2(r+w/2, c,w/2,floor+1);//下左
if(tran[floor] == 4) dfs2(r+w/2,c+w/2,w/2,floor+1);//下右
}
int main()
{
int n,kcase=0;
while(cin >> n && n){
if(kcase) cout<<endl;//这个是坑!
cout <<"Image "<<++kcase<<endl;
if(n > 0){
for(int i=0;i<n;i++) cin >>marix[i];
node.clear();
dfs1(0,0,n,0,0);
sort(node.begin(),node.end());//将结点排序
for(int i=0;i<node.size();i++){//将结点输出,每行最多12个
cout <<node[i];
if((i+1)%12 == 0 || i == node.size()-1) cout<<endl;
else cout<<" ";
}
cout << "Total number of black nodes = "<<node.size()<<endl;
}else{
int a[10000],index=0;
while(cin>>a[index] && a[index++] != -1);
index--;
memset(marix,'.',sizeof(marix));
for(int i=0;i<index;i++){
len = translate(a[i],tran);
dfs2(0,0,-n,0);
}
for(int i=0;i<-n;i++){
for(int j=0;j<-n;j++) cout << marix[i][j];
cout<<endl;
}
}
}
return 0;}