poj1623 象限四分树

来源:互联网 发布:延保服务 知乎 编辑:程序博客网 时间:2024/06/15 20:29
Squadtrees
Time Limit: 10000MS Memory Limit: 32768KTotal Submissions: 389 Accepted: 143

Description

Quadtrees are data structures used to store digital images. For our purposes, the images will be simple bitmaps, where every pixel is either a 1 (black) or a 0 (white). A quadtree representation of a bitmap is obtained as follows: first, associate the root node with the entire image. If the entire image is either all 1's or all 0's, then store that value in the node and you're done. Otherwise divide the region into four equal size quadrants, add four children to the root, and assign each child one of the four regions in the following order: the first child gets the upper left quadrant, the second the upper right, the third the lower left and the fourth the lower right. Then recursively apply the above rules to each of the children. 
For example, the 4x4 image on the left would be represented by the quadtree on the right: 

Note that this procedure only works as stated if the image is a square and has a side length equal to a power of 2. For those images which do not meet those requirements, we pad the rows and columns with 0's (on the right and on the bottom, respectively) until we have a bitmap of the appropriate size.For example, a 5x13 image would be converted to a 16x16 bitmap (with the original image residing in the upper left portion, and the remainder of the image filled with 0's). 
While quadtrees can result in a significant savings in space over the original image, even more savings can be achieved if we identify repeated subtrees. For example, in the tree above, the first and third subtrees of the root are identical, so we could replace the root of the third subtree with a reference to the first subtree, obtaining something that symbolically looks like the following: 

We will call these compressed quadtrees super quadtrees, or squadtrees. For our purposes the use of a reference saves space only when the tree it replaces has height of at least 1. Thus, while we could replace 5 of the nodes which contain a B with references to the first node with a B, this would not in practice save any space in the compression. Using this rule, our squadtree contains only 12 nodes, as opposed to 17 in the original quadtree. Your job for this problem is to take a set of images and determine the number of nodes in both the resulting quadtrees and squadtrees.

Input

Input will consist of multiple problem instances. Each instance will start with a single line containing two integers n and m, indicating the number of rows and columns in the image. The maximum values for these integers is 128. The next n lines will each contain m characters representing the image to process. A black pixel will be represented by a '1', and a white pixel will be represented by a '0'. The input line 0 0 will terminate input and should not be processed.

Output

For each problem instance, output two integers separated by a single space. The first value is the number of nodes in the quadtree for the problem instance, and the second is the number of nodes in the squadtree.

Sample Input

4 410110111101001116 71110111101010100000000100010101110110101010 0

Sample Output

17 1261 24


递归写法简单有高效,轻松摘得POJ第一。。。

代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct state{    int s1,s2,s3,s4;    state(){}    state(int n1,int n2,int n3,int n4){        s1=n1,s2=n2,s3=n3,s4=n4;    }    bool check(int n1,int n2,int n3,int n4){        return s1==n1&&s2==n2&&s3==n3&&s4==n4;    }}p[10010];int tot;char s[130][130];int a[130][130];int vis[20];int c1,c2;int div(int x1,int y1,int x2,int y2){    int tmp=c1;    c1++,c2++;    if(x1==x2&&y1==y2) return a[x1][y1];    int x3=x1+x2>>1,y3=y1+y2>>1;    int d1=div(x1,y1,x3,y3);    int d2=div(x1,y3+1,x3,y2);    int d3=div(x3+1,y1,x2,y3);    int d4=div(x3+1,y3+1,x2,y2);    if(d1==0&&d2==0&&d3==0&&d4==0) {c1-=4,c2-=4;return 0;}    if(d1==1&&d2==1&&d3==1&&d4==1) {c1-=4,c2-=4;return 1;}    for(int i=2;i<tot;i++)        if(p[i].check(d1,d2,d3,d4)){            c1=tmp;            return i;        }    p[tot++]=state(d1,d2,d3,d4);    return tot-1;}int main(){    int n,m;    while(cin>>n>>m,n){        memset(a,0,sizeof a);        for(int i=0;i<n;i++){            scanf("%s",s[i]);            for(int j=0;s[i][j];j++)                a[i][j]=s[i][j]-'0';        }        int k=1;        if(n<m) swap(n,m);        while(k<n) k<<=1;        memset(vis,0,sizeof vis);        tot=2,c1=c2=0;        div(0,0,k-1,k-1);        printf("%d %d\n",c2,c1);    }    return 0;}



0 0
原创粉丝点击