UVa 297 四分树
2014-08-27 12:38
204 查看
题意:每张图片可分为1024个像素,用四叉树结构表示。最高高度5。每个像素或黑或白,即或1或0.现将两个这样的图,即树合并,同一位置的像素其中一张是黑,则结果是黑色。求最终合并的图中有多少黑像素。
思路:最直接的思路就是构建四叉树,然后对两个四叉树进行合并对比吧。把四叉树建好之后,发现不会合并了,想了下,很复杂。网搜的有对比四叉树以及填充数组这两种思路。其中有一个直接没有建树、填数组就行了,没仔细看。最终我在四叉树建好之后,让叶子结点或者说 f 结点来填数组,两棵树各填一次,最终统计1的个数。
建树的时候是利用栈,只将 p 结点入栈,给栈顶元素赋满四个孩子后出栈。 后面处理是用深搜,递归实现。只不过在遇到 f 结点时进行填数组。
建树方面还是比较顺利的,就是后面处理纠结了很长时间,察觉到“对每个结点填数组可以递归地设定填的起始位置和宽度”后还是很容易写的。没什么小错误,就是最后输出的地方输出的是句子不是单个数字,WA了一次。。 要学会用递归
方法一 - Code:
方法二 - Code:
可以发现在递归填数组时是可以建树的,所以可以将两个过程合并。用递归法建树,并在建树过程中填数组。AC后时间比上一个稍长一点,不知道是递归的原因还是每次测试数据不同的原因。。
思路:最直接的思路就是构建四叉树,然后对两个四叉树进行合并对比吧。把四叉树建好之后,发现不会合并了,想了下,很复杂。网搜的有对比四叉树以及填充数组这两种思路。其中有一个直接没有建树、填数组就行了,没仔细看。最终我在四叉树建好之后,让叶子结点或者说 f 结点来填数组,两棵树各填一次,最终统计1的个数。
建树的时候是利用栈,只将 p 结点入栈,给栈顶元素赋满四个孩子后出栈。 后面处理是用深搜,递归实现。只不过在遇到 f 结点时进行填数组。
建树方面还是比较顺利的,就是后面处理纠结了很长时间,察觉到“对每个结点填数组可以递归地设定填的起始位置和宽度”后还是很容易写的。没什么小错误,就是最后输出的地方输出的是句子不是单个数字,WA了一次。。 要学会用递归
方法一 - Code:
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXN 100 typedef struct qnode { int data; struct qnode *y,*e,*sa,*si; }Qnode; void count(); void dfs(Qnode *r,int fw,int st); void fill(int st,int fw); Qnode* build(); Qnode* newnode(); void remove_tree(Qnode *root); int pix[1024]; int main() { int n=0; scanf("%d",&n); getchar(); while(n-->0) { Qnode* root1=build(); Qnode* root2=build(); memset(pix,0,sizeof(pix)); dfs(root1,1024,0); dfs(root2,1024,0); count(); remove_tree(root1); remove_tree(root2); } return 0; } void count() { int cnt=0; for(int i=0;i<1024;++i) if(pix[i]) cnt++; printf("There are %d black pixels.\n",cnt); } void dfs(Qnode *r,int fw,int st) {//st为数组应填的起始下标,fw为要填充的宽度或范围。 if(r==NULL) return ; if(r->data==1) fill(st,fw); else if(r->data==2) { dfs(r->y,fw>>2,st); dfs(r->e,fw>>2,st+(fw>>2));//加号的优先级比右移高。另外,除以4是右移2不是右移4。。。 dfs(r->sa,fw>>2,st+2*(fw>>2)); dfs(r->si,fw>>2,st+3*(fw>>2)); } } void fill(int st,int fw) {//st为数组应填的起始下标,fw为要填充的宽度或范围。 for(int i=0;i<fw;++i) pix[st+i]=1; //printf("st:%d~%d\n",st,st+fw-1); } Qnode* build() { char c; Qnode* stack[MAXN]; int top=0; int flag=0; Qnode *root=NULL; while((c=getchar())&&c!='\n') { Qnode *u=newnode(); if(top) { Qnode *t=stack[top]; if(t->y==NULL) t->y=u; else if(t->e==NULL) t->e=u; else if(t->sa==NULL) t->sa=u; else if(t->si==NULL) {//有四个孩子,出栈 t->si=u; top--; } } if(c=='p') {//入栈 u->data=2; stack[++top]=u; } else if(c=='e') { u->data=0; } else if(c=='f') { u->data=1; } if(!flag) {root=u; flag=1;} } return root; } Qnode* newnode() { Qnode* u=(Qnode*)malloc(sizeof(Qnode)); if(u!=NULL) { u->data=-1; u->y=u->e=u->sa=u->si=NULL; } return u; } void remove_tree(Qnode *root) { if(root!=NULL) { remove_tree(root->y); remove_tree(root->e); remove_tree(root->sa); remove_tree(root->si); free(root); } }
方法二 - Code:
可以发现在递归填数组时是可以建树的,所以可以将两个过程合并。用递归法建树,并在建树过程中填数组。AC后时间比上一个稍长一点,不知道是递归的原因还是每次测试数据不同的原因。。
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXN 100 typedef struct qnode { char data; struct qnode *y,*e,*sa,*si; }Qnode; void count(); Qnode* dfs(int st,int fw); void fill(int st,int fw); Qnode* newnode(); void remove_tree(Qnode *root); int pix[1024]; int main() { int n=0; scanf("%d",&n); getchar(); while(n-->0) { memset(pix,0,sizeof(pix)); Qnode* root1=dfs(0,1024); getchar(); Qnode* root2=dfs(0,1024); getchar(); count(); remove_tree(root1); remove_tree(root2); } return 0; } void count() { int cnt=0; for(int i=0;i<1024;++i) if(pix[i]) cnt++; printf("There are %d black pixels.\n",cnt); } Qnode* dfs(int st,int fw) { char c=getchar(); Qnode* u=newnode(); u->data=c; if(c=='e') return u; if(c=='f') { fill(st,fw); return u; } if(c=='p') { u->y=dfs(st,fw>>2); u->e=dfs(st+(fw>>2),fw>>2); u->sa=dfs(st+2*(fw>>2),fw>>2); u->si=dfs(st+3*(fw>>2),fw>>2); return u; } } void fill(int st,int fw) {//st为数组应填的起始下标,fw为要填充的宽度或范围。 for(int i=0;i<fw;++i) pix[st+i]=1; //printf("st:%d~%d\n",st,st+fw-1); } Qnode* newnode() { Qnode* u=(Qnode*)malloc(sizeof(Qnode)); if(u!=NULL) { u->data=-1; u->y=u->e=u->sa=u->si=NULL; } return u; } void remove_tree(Qnode *root) { if(root!=NULL) { remove_tree(root->y); remove_tree(root->e); remove_tree(root->sa); remove_tree(root->si); free(root); } }
相关文章推荐
- UVa 297 (四分树 递归) Quadtrees
- uva-297 四分树
- 四分树(Uva 297)
- 例题6-11 四分树(Quadtrees, UVa 297)
- UVA - 297Quadtrees(四分图)
- 6-11 四分树(Quadtrees, UVa 297)
- UVa 297 Quadtrees(模拟&四分树)
- UVA - 297 Quadtrees(四分图)
- Quadtrees UVA 297 四分树
- UVa297 例题6-11 四分树(Quadtrees)
- Uva-297 - Quadtrees(四分树与结构体指针)
- 6_11 四分树(UVa297)<四分树>
- 四分树--uva297
- 例题 6-11 四分树 UVa 297
- 例题:四分树(UVa 297)
- UVA-297 Quadtrees (四分树)
- uva 297 四分树
- 例题6-11 UVa297 Quadtrees(四分树)
- uva 297 Quadtrees 四分树
- UVA.297 Quadtrees (四分树 DFS)