题意翻译
一个四分树是由一个方格的结构组成的,如图:(就是上面的三个图)。
那些像素点可以构成一个四分树,如图:(就是上面的那个树)。
我们规定,NW=1,NE=2,SW=3,SE=4
,而一个节点所构成的数字串可以认为是一个五进制数,将它们排序后输出。
例如:上图中地四号节点的路径为NE,SW,所以是
32(5进制) = 17(十进制)
那么上树所对应的一传数列为:(在十进制下)9 14 17 22 23 44 63 69 88 94 113
你的任务是在这两者之间转换。
注意,数串中的数字顺序是从叶子到根的,别搞错了。
输入格式:
先输入一个nn,|n|表示这个正方形的边长(|n| < 64)如果nn是正数,那么输入一个n\times nn×n由00和11方阵(00代表这个点是黑的,11代表这个点是白的)。如果nn是负数,那么就会跟着一串数,表示最后矩阵所对的数列,以-1结束。
输出格式:
如果输入的是一个方阵,输出所有黑点的路径转化并排序后的结果,后面跟着一个数,表示黑色节点数。注意每1212个换一行。
如果输入的是一串数没那么输出它所对应的方阵。
每一个数据后面请空一行,最后不要空行,结尾不要有多余的空格。
输入输出样例
输入
8
00000000
00000000
00001111
00001111
00011111
00111111
00111100
00111000
-8
9 14 17 22 23 44 63 69 88 94 113 -1
2
00
00
-4
0 -1
0
输出
Image 1
9 14 17 22 23 44 63 69 88 94 113
Total number of black nodes = 11
Image 2
........
........
....****
....****
...*****
..******
..****..
..***...
Image 3
Total number of black nodes = 0
Image 4
****
****
****
****
思路
这题其实就是两个目的
- 给一张矩阵,翻译出它代表的5进制数们
- 给一堆数,画出代表他们的矩阵
将一个矩阵分为四块,如果进入左上,代表进入树的1节点,右上2节点,左下3,右下4
进入树的深度为h的层的x号节点,所代表的数就要加 【5的h-1 次方】* x
对于问题1,dfs即可解决
- 如果一个区域内全是1,那么这个区域就是叶子节点,最终的结果就是走过来的路径和
- 否则,递归上左,上右,下左,下右四个区域,递归进去的时候,更新路径和,路径和 += 【5 的深度-1 次方】*方向,并且深度+1
对于问题2,也是dfs
- 先将整数转换为五进制的串
- 然后从结尾开始,如果是1,就递归进左上,2进右上,3进左下,4进右下,并且删除结尾
- 直到空串,如果是空串,填满当前区域
代码
#include <bits/stdc++.h>
using namespace std;
void dfs(int x, int y, int len, vector<int>& seq, vector<string> &a, int sum, int depth)
{
int cnt=0;
for(int i=x; i<x+len; i++)
for(int j=y; j<y+len; j++)
if(a[i][j]=='1') cnt++;
if(cnt==len*len)
{
seq.push_back(sum);
return;
}
if(len==1) return;
dfs(x, y, len/2, seq, a, sum+pow(5, depth)*1, depth+1);
dfs(x+len/2, y+len/2, len/2, seq, a, sum+pow(5, depth)*4, depth+1);
dfs(x+len/2, y, len/2, seq, a, sum+pow(5, depth)*3, depth+1);
dfs(x, y+len/2, len/2, seq, a, sum+pow(5, depth)*2, depth+1);
}
void mat2seq(int n)
{
vector<string> a(n); for(int i=0; i<n; i++) cin>>a[i];
vector<int> seq;
dfs(0, 0, n, seq, a, 0, 0);
sort(seq.begin(), seq.end());
if(seq.size()>0)
{
for(int i=0; i<seq.size(); i++)
cout<<seq[i]<<" ";
cout<<endl;
}
cout<<"Total number of black nodes = "<<seq.size()<<endl;
}
string tofive(int x)
{
if(x==0) return "";
if(x==1) return "1";
if(x==2) return "2";
if(x==3) return "3";
if(x==4) return "4";
int n=0, res;
while(pow(5, n)<x) n++;
n--; res=x/pow(5, n);
return (char)(res+'0') + tofive(x%(int)pow(5, n));
}
void dfs2(int x, int y, int len, vector<string> &a, string& seq)
{
if(seq.length()==0)
{
for(int i=x; i<x+len; i++)
for(int j=y; j<y+len; j++) a[i][j]='*';
return;
}
int dir=seq.back()-'0'; seq.pop_back();
if(dir==1) dfs2(x, y, len/2, a, seq);
if(dir==2) dfs2(x, y+len/2, len/2, a, seq);
if(dir==3) dfs2(x+len/2, y, len/2, a, seq);
if(dir==4) dfs2(x+len/2, y+len/2, len/2, a, seq);
}
void seq2mat(int n)
{
vector<string> seq;
int t;
while(1)
{
cin>>t; if(t<0) break;
seq.push_back(tofive(t));
}
vector<string> a(n);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++) a[i].push_back('.');
for(int i=0; i<seq.size(); i++)
dfs2(0, 0, n, a, seq[i]);
for(int i=0; i<n; i++) cout<<a[i]<<endl;
}
int main()
{
int n, t=0;
while(1)
{
cin>>n;
if(n==0) break;
t++;
cout<<"Image "<<t<<endl;
if(n>0) mat2seq(n);
else if(n<0) seq2mat(-n);
}
return 0;
}