题目描述

四象树是每个内结点均有4个子结点的特殊四叉树,它可用于描述平面上黑白图像。平面上的黑白图像是32行×32列的正方形,每个格子称为1个象素,是最小的图像单位。正方形图像可分成四个相等的小正方形,可按直角坐标系四个象限的顺序分别编号1,2,3,4,分别对应于四象树的四个子结点。这样,32行×32列的图像就对应于一棵深度为6的完全四叉树,最底层的每个叶结点正好对应于一个象素。但我们可以压缩四象树的结点数量。

当图像上某个区域为全白或者全黑时,可把该区域在四象树上对应的结点描述为全白(用小写字母e表示)或者全黑(用小写字母f表示),并且对这样的结点不再扩展子结点,因为再扩展出的子树上每个结点都是相同的颜色。

只有当图像上某个区域为“杂色”时,才继续划分成四个子区域(在四象树上对应的结点用小写字母p表示),然后“纯”色的子区域也不再扩展,并继续扩展“杂”色子区域。例如,下图左、中两个图像可分别用它们下边的四象树描述。

我们感兴趣的问题是:当两个大小均为32*32的黑白图像叠加后,合成的新图像是什么样子。合成的规则是:当一个图像上某个区域为全黑时,新图像的这个区域即为全黑;当一个图像上某个区域为全白时,新图像的这个区域的颜色是另加一个图像上这个区域的颜色。上图准确地示例了本合成的规则。

我们给出两个图像对应四象树的先序遍历顺序,求合成后的图像中,黑色象素点的数量。

输入

多组测试数据,第1行一个整数T,表示测试数据的组数,每组数据的格式为:

第1行:一个字符串,描述第1棵四象树的先序序列

第2行:一个字符串,描述第2棵四旬树的先序序列

输出

对每组数据,在单独一行上输出一个整数,表示合成后的图像上黑色象素的数量,格式如输出样例所示:

样例输入

3
ppeeefpffeefe
pefepeefe
peeef
peefe
peeef
peepefefe

样例输出

There are 640 black pixels.
There are 512 black pixels.
There are 384 black pixels.

我直接把BZOJ的翻译粘过来了(逃

思路1:数据量很小。我第一次写时直接模拟了两棵四叉树的建树与搜索,然后捎带着把最后的黑色个数算出来了。其中黑色结点的值跟它的深度有关,写一写就能找到规律。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std; struct node
{
char c;
node *ptr[];
node(){for (int i = ; i < ; i++) ptr[i] = NULL;}
}; node *root1, *root2; int sum, cnt;//sum是最终结果,cnt是记录字符串走到哪个位置了 void release(node *root)//释放
{
if (!root) return;
for (int i = ; i < ; i++)
release(root->ptr[i]);
delete root;
} void build(string cur, node *&root)//建树,记得root要加地址符
{
root = new node();
root->c = cur[cnt++];
if (root->c == 'p')
for (int i = ; i < ; ++i)
{
root->ptr[i] = new node();
build(cur, root->ptr[i]);
}
} void dfs(node *root1, node *root2, int depth)
{
//大概分了三种情况讨论
if (root1->c == 'f' || root2->c == 'f')//有一个是黑
{
sum += pow(,-depth);//数学可推……
return;
}
else if (root1->c == 'e' && root2->c == 'e')//全是白
return;
//对于'p'的点深搜
bool flag1 = root1->c=='p', flag2 = root2->c=='p';
node *x = root1, *y = root2;
for (int i = ; i < ; i++)
{
if (flag1) x = root1->ptr[i];
if (flag2) y = root2->ptr[i];
dfs(x, y, depth+);
}
} int main()
{
int test;
scanf("%d", &test); while (test--)
{
sum = ;
string s,t;
cin >> s >> t;
cnt = , build(s, root1);
cnt = , build(t, root2); dfs(root1, root2, ); printf("There are %d black pixels.\n", sum); release(root1),release(root2);
} return ;
}

思路2:书上代码思路是在32*32的正方形里面涂色然后查找,貌似跟树也没什么关系了……书中的注释已经很明白了,见代码。(PS:UVA有毒)

 #include <cstdio>
#include <cstring> const int len = ;
const int maxn = + ;
//下面这个char数组和int变量定义顺序变一下UVA居然会WA啊!
//我从未见过如此厚颜无耻之OJ
char s[maxn];
int buf[len][len], cnt; //把字符串s[p..]导出到以(r,c)为左上角,边长为w的缓冲区中
//2 1
//3 4
void draw(const char* s, int& p, int r, int c, int w)
{
char ch = s[p++];
if (ch == 'p')
{
draw(s, p, r , c+w/, w/);//
draw(s, p, r , c , w/);//
draw(s, p, r+w/, c , w/);//
draw(s, p, r+w/, c+w/, w/);//
}
else if (ch == 'f')
for (int i = r; i < r+w; i++)
for (int j = c; j < c+w; j++)
if (buf[i][j] == )
buf[i][j] = ,cnt++;
} int main()
{
int t;
scanf("%d", &t); while (t--)
{
memset(buf, , sizeof(buf));
cnt = ;
for (int i = ; i < ; i++)
{
scanf("%s",s);
int p = ;
draw(s, p, , , len);
} printf("There are %d black pixels.\n", cnt); } return ;
}

最新文章

  1. 警惕!高版本VS发布时预编译导致Mono中Razor找不到视图
  2. [笔记]ubuntu安装flashplayer
  3. Ubuntu下安装QQ22013
  4. 2014——&gt;2015,我的薪资依然是4.5
  5. ubuntu 14.04安装右键打开终端功能
  6. js 和 jq 控制 checkbox
  7. SAE上安装第三方模块
  8. IOS 蓝牙相关-BabyBluetooth蓝牙库介绍(4)
  9. jquery之ajax
  10. Memcached使用
  11. Linux错误码的含义
  12. C# KTV 系统 SQL数据库连接 C# 应用窗体
  13. 一些关于poi导入的样例
  14. C#调用HTTP接口
  15. 配置 .vimrc 解决 Vim / gVim 在中文 Windows 下的字符编码问题
  16. javascript 生成 uuid
  17. jar包后台启动--nohup篇
  18. Spring Boot中使用使用Spring Security和JWT
  19. Python-Pool类
  20. [CentOS7][ssh][publickey][troubleshoot] 通过密钥登录ssh故障排查

热门文章

  1. dhcpcd守护进程分析【转】
  2. Struts2基础知识
  3. 【应用】图片翻转js
  4. python中的linspace,meshgrid,concatenate函数
  5. CopyOnWrite 策略
  6. Java操作系统硬件的方法Unsafe
  7. docker学习 (三) Windows 10 安装Docker
  8. EasyUI 下载与引用
  9. Android开发--数据存储之数据库操作
  10. 关于checkbox对应一张表时如何遍历