Spatial Structures

Computer graphics, image processing, and GIS (geographic information systems) all make use of a data
structure called a quadtree. Quadtrees represent regional or block data efficiently and support efficient
algorithms for operations like the union and intersection of images.
A quadtree for a black and white image is constructed by successively dividing the image into four
equal quadrants. If all the pixels in a quadrant are the same color (all black or all white) the division
process for that quadrant stops. Quadrants that contain both black and white pixels are subdivided
into four equal quadrants and this process continues until each subquadrant consists of either all black
or all white pixels. It is entirely possible that some subquadrants consist of a single pixel.
For example, using 0 for white and 1 for black, the region on the left below is represented by the
matrix of zeros and ones in the middle. The matrix is divided into subquadrants as shown on the right
where gray squares represent subquadrants that consist entirely of black pixels.
A quadtree is constructed from the block structure of an image. The root of the tree represents the
entire array of pixels. Each non-leaf node of a quadtree has four children, corresponding to the four
subquadrants of the region represented by the node. Leaf nodes represent regions that consist of pixels
of the same color and thus are not subdivided. For example, the image shown above, with the block
structure on the right, is represented by the quadtree below.
Leaf nodes are white if they correspond to a block of all white pixels, and black if they correspond
to a block of all black pixels. In the tree, each leaf node is numbered corresponding to the block it
represents in the diagram above. The branches of a non-leaf node are ordered from left-to-right as
shown for the northwest, northeast, southwest, and southeast quadrants (or upper-left, upper-right,
lower-left, lower-right).
A tree can be represented by a sequence of numbers representing the root-to-leaf paths of black
nodes. Each path is a base five number constructed by labeling branches with 1, 2, 3, or 4 with NW =
1, NE = 2, SW = 3, SE = 4, and with the least significant digit of the base five number corresponding
to the branch from the root. For example, the node labeled 4 has path NE, SW which is 325 (base 5)
or 1710 (base 10); the node labeled 12 has path SW, SE or 435 = 2310 ; and the node labeled 15 has
path SE, SW, NW or 1345 = 4410 . The entire tree is represented by the sequence of numbers (in base
10)
9 14 17 22 23 44 63 69 88 94 113
Write a program that converts images into root-to-leaf paths and converts root-to-leaf paths into
images.
Input
The input contains one or more images. Each image is square, and the data for an image starts with
an integer n, where |n| is the length of a side of the square (always a power of two, with |n| < 64)
followed by a representation of the image. A representation is either a sequence of n
2
zeros and ones
comprised of |n| lines of |n| digits per line, or the sequence of numbers that represent the root-to-leaf
paths of each black node in the quadtree that represents the image.
If n is positive, the zero/one representation follows; if n is negative, the sequence of black node
path numbers (in base 10) follows. The sequence is terminated by the number -1. A one-node tree
that represents an all-black image is represented by the number 0. A one-node tree that represents an
all-white image is represented by an empty sequence (no numbers).
The end of data is signaled by a value of 0 for n.
Output
For each image in the input, first output the number of the image, as shown in the sample output.
Then output the alternate form of the image.
If the image is represented by zeros and ones, the output consists of root-to-leaf paths of all black
nodes in the quadtree that represents the image. The values should be base 10 representations of the
base 5 path numbers, and the values should be printed in sorted order. If there are more than 12 black
nodes, print a newline after every 12 nodes. The total number of black nodes should be printed after
the path numbers.
If the image is represented by the root-to-leaf paths of black nodes, the output consists of an ASCII
representation of the image with the character ‘.’ used for white/zero and the character ‘’ used for
black/one. There should be n characters per line for an n × n image.
Sample Input
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
Sample Output
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





代码

#include<bits/stdc++.h>
using namespace std;
char line[77][77];
char numline[77][77];
vector<int> num;
vector<int> linenum;
int five[7]={1,5,25,125,625,3125,15625};
int dir[7][7]={{0,0},{0,1},{1,0},{1,1}};
bool check0(int x,int y,int n1)
{
    for(int i=x;i<x+n1;i++)
        for(int j=y;j<y+n1;j++)
            if(line[i][j]=='0')
                return false;
    return true;
}
bool check1(int x,int y,int n1)
{
    for(int i=x;i<x+n1;i++)
        for(int j=y;j<y+n1;j++)
            if(line[i][j]=='1')
                return false;
    return true;
}
void dfs(int x,int y,int n1,int nu,int k)
{
    for(int i=0;i<4;i++)
    {
        int n2=n1/2;
        int x1=x+dir[i][0]*n2;
        int y1=y+dir[i][1]*n2;
        int nu1=(i+1)*five[k]+nu;
        if(check0(x1,y1,n2))
        {
            linenum.push_back(nu1);
            continue;
        }
        if(check1(x1,y1,n2))
            continue;
        dfs(x1,y1,n2,nu1,k+1);
    }
}
int main()
{
    //freopen("F:\\1234.txt","r",stdin);
    //freopen("F:\\12345.txt","w",stdout);
    int n;
    int kase=0;
    while(cin>>n&&n!=0)
    {
        kase++;
        if(kase!=1)
            cout<<endl;
        if(n>0)
        {
            for(int i=0;i<n;i++)
                cin>>line[i];
            cout<<"Image "<<kase<<endl;
            if(!check0(0,0,n))
                if(!check1(0,0,n))
                    dfs(0,0,n,0,0);
            if(check0(0,0,n))
                linenum.push_back(0);
            sort(linenum.begin(),linenum.end());
            if(linenum.size())
            {
                int k=linenum.size();
                for(int i=0;i<k;i++)
                {
                    if(i%12==0&&i!=0)
                        cout<<endl;
                    if(i%12!=0)
                        cout<<" ";
                    cout<<linenum[i];
                }
                cout<<endl;
            }
            cout<<"Total number of black nodes = "<<linenum.size()<<endl;
            memset(line,0,sizeof(line));
            linenum.clear();
        }
        else
        {
            n=-n;
            int a;
            while(cin>>a&&a!=-1)
                num.push_back(a);
            cout<<"Image "<<kase<<endl;
            if(num.size())
            {
                if(num[0]==0)
                {
                    for(int i=0;i<n;i++)
                        for(int j=0;j<n;j++)
                            numline[i][j]='*';
                }
                else
                {
                    vector<int> aa;
                    int k=num.size();
                    for(int i=0;i<k;i++)
                    {
                        aa.clear();
                        while(num[i])
                        {
                            aa.push_back(num[i]%5);
                            num[i]/=5;
                        }
                        int x=0,y=0,n1=n;
                        int k1=aa.size();
                        for(int j=0;j<k1;j++)
                        {
                            n1/=2;
                            x+=dir[aa[j]-1][0]*n1;
                            y+=dir[aa[j]-1][1]*n1;
                        }
                        for(int i=x;i<x+n1;i++)
                            for(int j=y;j<y+n1;j++)
                                numline[i][j]='*';
                    }
                }
            }
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(numline[i][j]=='*')
                        cout<<numline[i][j];
                    else
                        cout<<'.';
                }
                cout<<endl;
            }
            num.clear();
            memset(numline,0,sizeof(numline));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43797508/article/details/88695902