1788

// 2007-02-13 23:21:10    Accepted    1788    C++    00:00.18    3236K
// 用时1小时15分,读题时间 =0,第二次做 ,一次AC 
/*

用数组存放4-树,Tree[0]为根
Tree[i]的四个儿子是Tree[4*i+1],Tree[4*i+2],Tree[4*i+3],Tree[4*i+4]
若i!=0,Tree[i]的父亲是Tree[(i-1)/4]
设N是输入的矩阵阶数
树的高度high=log(N)/log(2)
树的总占空间大小为4^0+4^1+4^2+...+4^high=(4^(high+1)-1)/3=(4*N*N-1)/3
当N=512时,上式=349525
*/
#include 
< iostream >
#include 
< vector >
#include 
< stack >
using   namespace  std;

int  Tree[ 349525 ],high,tree_size;
int  a[ 512 ][ 512 ],N;

int   * treep;

void  dfs( int  size, int  i, int  j)
{
    
if (size == 1 ){
        
*-- treep = a[i][j];
    }
    
else  {
        dfs(size
/ 2 ,i + size / 2 ,j + size / 2 );
        dfs(size
/ 2 ,i + size / 2 ,j);
        dfs(size
/ 2 ,i,j + size / 2 );
        dfs(size
/ 2 ,i,j);
    }
}

bool  eq( int  a, int  b, int  c, int  d, int  e)
{
    
// printf("%d %d %d %d %d",a,b,c,d,e);
     if (a != b) return   0 ;
    
if (b != c) return   0 ;
    
if (c != d) return   0 ;
    
if (d != e) return   0 ;
    
return   1 ;
}

int  main()
{
    
int  k;
    scanf(
" %d " , & k);
    
while (k -- ){
        scanf(
" %d " , & N);
        high
= 0 ;
        
while (( 1 << high) != N){
            high
++ ;
        }
        tree_size
= ( 4 * N * N - 1 ) / 3 ;
        treep
= Tree + tree_size; // 定位在树的最后一个空间的后面一个位置
         for ( int  i = 0 ;i < N;i ++ ){
            
for ( int  j = 0 ;j < N;j ++ ){
                scanf(
" %d " , & a[i][j]);
            }
        }
        
        dfs(N,
0 , 0 ); // 初始化树的叶子结点
        
        
/* 利用叶子结点计算整个树
        结点和值的对应方法如下
        (0,0)->0,(0,1)->1,1->2,    null->-1
*/
        
int *  treep2 = Tree + tree_size;
        
while (treep != Tree){
            treep2
-= 4 ;
            
if (eq(treep2[ 0 ],treep2[ 1 ],treep2[ 2 ],treep2[ 3 ], 1 )){
                
*-- treep = 1 ;
                treep2[
0 ] = treep2[ 1 ] = treep2[ 2 ] = treep2[ 3 ] =- 1 ;
            }
            
else   if (eq(treep2[ 0 ],treep2[ 1 ],treep2[ 2 ],treep2[ 3 ], 0 )){
                
*-- treep = 0 ;
                treep2[
0 ] = treep2[ 1 ] = treep2[ 2 ] = treep2[ 3 ] =- 1 ;
            }
            
else  {
                
*-- treep = 2 ;
            }
        }
        
        
// 将二进制串压入vector,顺序遍历Tree[]即为BFS
        vector < int >  V;
        
for ( int  i = 0 ;i < tree_size;i ++ ){
            
switch (Tree[i]){
            
case   0 :
                V.push_back(
0 );                
                V.push_back(
0 );
                
break ;
            
case   1 :
                V.push_back(
0 );
                V.push_back(
1 );
                
break ;
            
case   2 :
                V.push_back(
1 );
                
break ;
            }
        }
        
        
// 由二进制转换到16进制,压入栈
        stack < char >  S;
        vector
< int > ::iterator p;
        
for (p = V.end() - 1 ;p >= V.begin();){
            
int  sum( 0 );
            
if (p >= V.begin()  &&   * p -- )sum += 1 ;
            
if (p >= V.begin()  &&   * p -- )sum += 2 ;
            
if (p >= V.begin()  &&   * p -- )sum += 4 ;
            
if (p >= V.begin()  &&   * p -- )sum += 8 ;
            
if ( 0 <= sum  &&  sum < 10 ){
                S.push(sum
+ ' 0 ' );
            }
            
else {
                S.push(sum
- 10 + ' A ' );
            }
        }

        
// 输出
         while ( ! S.empty()){
            putchar(S.top());
            S.pop();
        }
        putchar(
' ' );
    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值