ZOJ 1011
来源:互联网 发布:淘宝主图点击率怎么看 编辑:程序博客网 时间:2024/06/07 03:31
ZOJ 1011 - NTA 英文题目
《算法分析与设计-以大学生程序设计竞赛为例》
算法分析
1. 样例分析
第一个完全二叉树如图。
参数n=4,m=2表示信号有4个,即0,1,2和3,后面两个信号2和3合法。
从根结点开始是信号0,信号发射单元是a,查表该结点产生信号(1,2),信号1给左,信号2给右,标注在结点的连线上,左子树的发射单元是b,可以产生两种信号:(0,2),(1,0)。程序会将这两种信号都向下遍历一遍,最后取信号(1,0)。重复该过程至所有结点。最后我们看到,所有叶子结点产生的信号,都是合法信号,即都是信号2和3,因此该树是有效的,输出单词 valid。
2. 信号发射表的数据结构
从样例看出,该表不是一个普通的二维表,表中元素的个数是不固定的。很容易想到的办法是建立一个二维数组,其中的元素是链表。这种数据结构是有效的,但使用起来肯定是麻烦的。
使用C++标准模板库的vector容器,可有效地解决数据存储问题。
// 定义信号的结构体struct signal { int left, right;};// 使用vector容器定义信号发射表vector<signal>table[20][20];// push_back()方法存集合元素signal pair; // 定义signal的变量scanf("%d%d", &pair.left, &pair.right);table[i][j].push_back(pair); // 构造集合
3. 信号数据的读取方法
读取信号数据很麻烦,因为不知道一行到底有多少数据。
可以把一行数据当作一个字符串,读取一行,然后再从字符串中读取数据,处理的工作量还是比较大的。实际上可以直接判断回车符,以判定当前行是否结束
实现代码如下。
// ---- 算法1 读取数据,构造信号发射表void readTable() { char ch; for(int i=0; i<n; i++) { table[i][j].clear(); while(true){ signal pair; // 定义signal的变量 scanf("%d%d", &pair.left, &pair.right); // 读取信号 table[i][j].push_back(pair); // 构造集合 ch = getchar(); if(ch == '\n') break; // 判断回车 } }}
4. 完全二叉树的数据结构
从根结点开始对树的结点按深度优先原则进行编号,根据结点编号node。
int left = node*2 + 1;
int right = left + 1;
使用一维数组存储了一颗完全二叉树:
char tree[1000];
树的构造在函数void readTree()中完成。其中treeDeep表示结点编号,从0到9,每读取一个结点,编号加1。当树构造完毕,treeDeep中存放了树的结点总数。
// ---- 算法2 构造完全二叉树void readTree() { char ch; treeDeep = 0; // 树结点从0开始编号 int i, j; // i表示树的每一行,j表示数的每一个结点 // treeLevel 是树的深度 for( i=0; i<=treeLevel; i++ ) { // 树的每一行 for( j=0; j<(1<<i); j++ ) { // 该行中树的每一个结点 cin >> ch; // 自动跳过空格 tree[treeDeep] = ch; // 形成树的结点 treeDeep++; // 产生下一个结点编号 } }}
5. 合法性判断
一颗完全二叉树的遍历与搜索,可以使用回溯算法。
在函数 bool judge( int signal, int node)中,signal表示传入该结点node的信号。
对结点node,要检查是不是为空“*”,或者超出总结点数 treeDeep。
(1)如果结点编号node>= treeDeep,表示其父结点是叶子结点,这时需要判断信号是不是合法的。如果是合法的,表示父结点产生的一对信号中,传过来的这个信号是合法的。
(2)对该结点的所有信号发射单元产生的信号逐一进行检查,如果所有的信号使其所到的叶子结点产生的信号都是非法的,则该树就是非法的。
// ---- 算法3 树的合法性判断// 形参signal表示该结点node的信号bool judge(int signal, int node) { int signal1, signal2; // if( tree[node]=='*' || node>=treeDeep ) { // if( signal<n-m ) return false; else return true; } // 结点的信号发射单元编号 int k1 = tree[node]-'a'; // 该结点的左子树编号 int left = node*2 + 1; // 该结点的右子树编号 int right = left + 1; // table[signal][k1].size()是信号发射表中,该结点链表的长度 for(int i=0; i<table[signal][k1].size(); i++) { signal1 = table[signal][k1][i].left; signal2 = table[signal][k1][i].right; if( judge(signal1, left) && judge(signal2, right) ) return true; } return false;}
英文积累
ZOJ 1011 - NTA 英文题目
acceptable signals 合法信号
auxiliary n.辅助
non-leaf node 非叶子结点
finite adj.有限的
signal-transmitting 信号发射
substance n.介质
non-deterministically 非确定性,随机
successor n.继承者(这里为子树)
for simplicity 简单起见
consecutive adj.连续的
configuration n.结构
代码实现
/** 题目来源:浙大ZOJ,编号1011,题名"NTA" URL:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1011 Author:Christina Finish Time:2017.09.26*/ #include#include using namespace std; struct signal // 信号 { int left,right; // 左右子树 }; vector table[20][20]; // 信号发射表 int n,m,k; // n是信号的个数,m是和发信号的个数,k是信号发射单元个数 int treeLevel; // 树的行数 char tree[1000]; // 定义一个完全二叉树 int treeDeep; // 树结点编号 /** * 信号数据读取的方法 * 可以把一行数据当作一个字符,读取一行,然后再从字符串中读取数据, * 处理的工作量还是比较大的。实际上可以直接判断回车符,以判断当前行是否结束 */ void readTable() { char ch; for(int i=0; i > ch; // 会自动跳过空格 tree[treeDeep] = ch; // 形成树的一个节点 treeDeep++; // 产生下一个节点 } } /** * 树的合理性判断 * (1)如果节点编号node>=treeDeep,表示其父类节点是叶子节点,这时需要判断信号是否合法。 * 如果合法,表示父节点产生的一对信号中,传过来的信号是合法的 * (2)对该节点的所有信号发射单元产生的信号逐一进行检查,如果所有的信号时期所有达到的叶子节点产生都是非法的, * 则该树就是非法的。 */ bool judge(int signal, int node) // signal表示传入该节点node的信号 { int signal1, signal2; if( tree[node]=='*' || node>=treeDeep ) // 叶子节点的合法性判断 if ( signal
- zoj 1011
- ZOJ 1011
- ZOJ 1011 NTA
- zoj 1011NTA
- ZOJ 1011 NTA (DFS)
- zoj 1011 NTA
- ZOJ 1011 NTA
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- ZOJ
- OpenGL光照基础
- 计蒜客 17313 Overlapping Rectangles
- redis学习
- 接口简介
- Git使用小结(2)
- ZOJ 1011
- 使用servlet来实现表单的登录机制并用filter来进行过滤操作
- 安装openssh-server报Depends: openssh-client (= 1:6.6p1-2ubuntu2.8)错误
- 补昨日博客-使用putty登录Windows实现虚拟机中的系统的开机、关机、重启
- Android事件分发机制——从基础深入源码解析
- shell '%'通配符和 '#' 通配符的使用
- Unity角色行为状态机框架设计
- Timeline--Activation Track
- Ubuntu 16.04-HBase1.3.1+Hadoop2.6.5 单机环境搭建