又是一周数算实习,马上就要上机考试了整个都要不好了,还好这一次的四分树作业给了我一丢丢的信心…
作业是禁止使用STL的,而且明确要求必须用空间数据结构,所以这道题本来可以用广搜写的很简单,但是为了满足作业需求我还是使用了四分树,并且用数组模拟了队列进行广搜,直接用队列广搜会有更好的效果。
总体思路就是根据每个区块的特点去建立一个四分树,四分树的每个结点就代表这一个区块的特性,如果state1的值为1,就意味着这个区块里面的数字既有1又有0,如果state1的值为0,那么这个区块里面所有的值都是一样的,并且这个值记录在state2里面。
用递归的方法建树,每次都判断自己这个区块是不是既有0又有1,如果是,那么分成四块继续计算,如果不是,直接state1的值变为0并且停止递归。
广搜的时候用数组模拟了队列,应该也没什么好多说的。在我的这个代码中重复编码的地方还是太多了,如果能把某个节点的四个指针放在一个指针数组里面,这样遍历或者初始化的时候能够方便很多,不过我也懒得修改了,就当提供一个思路。
再就是scan函数使用来前序遍历整个树来判断树有没有写对的,对整个程序没有影响,在遍历的时候我采用的是ACBD的顺序遍历结点,主要是因为我定义的xy和题目中的反过来了= =
#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;
#define maxn 520
bool map[maxn][maxn]={0};
bool output[4*maxn*maxn]={0};
int result[maxn]={0};
struct area{
int x1,y1,x2,y2;
};
struct node{
area a;
node *A, *B, *C, *D;
int state1;
int state2;
};
node* queue[4*maxn*maxn]={0};
void build(node* root){
bool one = 0, zero = 0;
area temp = root->a;
//cout<<"("<<temp.x1<<","<<temp.y1<<")"<<"("<<temp.x2<<","<<temp.y2<<")"<<endl;
for(int i=temp.x1;i<temp.x2;++i){
for(int j=temp.y1;j<temp.y2;++j){
if(map[i][j])
one = 1;
else
zero = 1;
if(one&&zero)
break;
}
if(one&&zero)
break;
}
if(one&&zero){
root->state1 = 1;
int midx = (temp.x1 + temp.x2)>>1;
int midy = (temp.y1 + temp.y2)>>1;
//printf("x1: %d x2: %d\n",temp.x1,temp.x2);
//printf("midx: %d midy: %d\n",midx,midy);
root->A = new node;
root->B = new node;
root->C = new node;
root->D = new node;
root->A->A = root->A->B = root->A->C = root->A->D = NULL;
root->B->A = root->B->B = root->B->C = root->B->D = NULL;
root->C->A = root->C->B = root->C->C = root->C->D = NULL;
root->D->A = root->D->B = root->D->C = root->D->D = NULL;
int x1 = temp.x1,x2 = temp.x2,y1 =temp.y1, y2 =temp.y2;
(root->A->a).x1 = x1; (root->A->a).y1 = y1; (root->A->a).x2 = midx; (root->A->a).y2 = midy;
build(root->A);
(root->B->a).x1 = midx; (root->B->a).y1 = y1; (root->B->a).x2 = x2; (root->B->a).y2 = midy;
build(root->B);
(root->C->a).x1 = x1; (root->C->a).y1 = midy; (root->C->a).x2 = midx; (root->C->a).y2 = y2;
build(root->C);
(root->D->a).x1 = midx; (root->D->a).y1 = midy; (root->D->a).x2 = x2; (root->D->a).y2 = y2;
build(root->D);
return;
}
else{
root->state1 = 0;
root->state2 = one;
}
return;
}
int BFS(node *root){
int start = 0,end = 0;
int ocount = 0;
queue[start] = root;
end++;
while(start<end){
//cout<<ocount<<endl;
node* temp = queue[start++];
if(temp->state1){
output[ocount++] = 1;
}
else{
output[ocount++] = 0;
output[ocount++] = temp->state2;
}
if(temp->A)
queue[end++] = temp->A;
if(temp->C)
queue[end++] = temp->C;
if(temp->B)
queue[end++] = temp->B;
if(temp->D)
queue[end++] = temp->D;
}
return ocount;
}
void scan(node* root){
if(!root)
return;
if(root->state1){
printf("(1) ");
}
else{
printf("(0,%d) ",root->state2);
}
scan(root->A);
scan(root->C);
scan(root->B);
scan(root->D);
return;
}
void trans(int n){
int overload = n%4;
int recount = 0;
int t = 0;
for(int i=overload - 1;i>=0;--i){
t += output[i]<<(overload-i-1);
}
result[recount++] = t;
int total = n/4;
//cout<<"total: "<<total<<endl;
for(int i=0;i<total;++i){
int start = overload + i*4;
/*for(int j=0;j<4;++j)
printf("%d ",output[j+overload]);
printf("\n");*/
int t = 0;
for(int j=0 ;j < 4;++j){
t+=output[j+start]<<(3-j);
}
result[recount++] = t;
}
for(int i=0;i<=total;++i)
printf("%X",result[i]);
printf("\n");
}
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(map,0,sizeof(map));
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
scanf("%d",&map[i][j]);
}
}
node *root = new node;
(root->a).x1 = 0;
(root->a).y1 = 0;
(root->a).x2 = n;
(root->a).y2 = n;
root->state1 = root->state2 = 0;
root->A = root->B = root->C = root->D = NULL;
build(root);
int total = BFS(root);
trans(total);
}
//system("pause");
return 0;
}