/* * zoj 1788 * poj 1610 * Quad Trees * 解题思路: * 首先定义四分树数据结构Node节点,然后建立四叉树,在建树函数中,判断所在区域的元素是否全部相等,如果不相等, * 则递归生成四个子节点,并把标志位unaccord置为true;如果相等,则把标志unaccord置为false。 * */ #include<iostream> #include<cstring> #include<string> #include<queue> #include<cmath> #include<algorithm> using namespace std; bool Image[520][520]; struct Node { bool unaccord; //该节点所在区域的元素是否全部一致 bool flag; //如果一致,该节点区域的元素 Node* child1; //节点的四个孩子 Node* child2; Node* child3; Node* child4; Node() { unaccord = flag = false; child1 = child2 = child3 = child4 = NULL; } }; //建树函数: Node* buildTree( int bx, int by, int len ) { Node *node = new Node(); node->flag = Image[bx][by]; //置节点元素标志为首元素 bool mark = false; for( int i=0; i<len; i++ ) //判断区域内元素是否一致 { for( int j=0; j<len; j++ ) { if( Image[bx][by] != Image[bx+i][by+j] ) { mark = true; break; } } if( mark ) break; } node->unaccord = mark; if( mark ) //如果元素不一致,则生成四个孩子 { node->child1 = buildTree( bx, by, len/2 ); node->child2 = buildTree( bx, by+len/2, len/2 ); node->child3 = buildTree( bx+len/2, by, len/2 ); node->child4 = buildTree( bx+len/2, by+len/2, len/2 ); } return node; } //层次遍历四叉树,返回遍历到的字符串: string traversingTree( Node* node ) { string str; queue< Node* > q; q.push( node ); while( !q.empty() ) //利用队列层次遍历 { Node* tmp = q.front(); q.pop(); str += (char)(tmp->unaccord + 48); //把是否一致的标志加入字符串 if( !tmp->unaccord ) { str += (char)(tmp->flag + 48); //如果区域内的元素全部一致,则在加入该区域的元素值 } if( tmp->child1 ) q.push( tmp->child1 ); if( tmp->child2 ) q.push( tmp->child2 ); if( tmp->child3 ) q.push( tmp->child3 ); if( tmp->child4 ) q.push( tmp->child4 ); } return str; } //将二进制字符串转换为16进制字符串: string convert( string str ) { string ret; int size = str.size()-1; int count; int c = (size+1) % 4; int i; while( size > c ) { count = 0; for( i=0; i<4; i++ ) { count += (str[size-i]-48)*pow( 2.0, (double)i ); } if( count >= 10 ) ret += ('A'+count-10); else ret += (char)(count+48); size -= 4; } if( c == 0 ) return ret; count = 0; int t = 0; for( i=c-1; i>=0; i-- ) { count += (str[i]-48)*pow( 2.0, (double)t ); t++; } ret += (char)(count+48); reverse( ret.begin(), ret.end() ); return ret; } int main() { string str; int k,n; cin>>k; while( k-- ) { cin>>n; memset( Image, 0, sizeof(Image) ); for( int i=0; i<n; i++ ) { for( int j=0; j<n; j++ ) { cin>>Image[i][j]; } } Node* root = buildTree( 0,0,n ); string str = traversingTree( root ); string res = convert( str ); cout<<res<<endl; } return 0; }