UVa 712/POJ 1105/ZOJ 1150 S-Trees(用数组模拟二叉树)

2024-03-05 21:08

本文主要是介绍UVa 712/POJ 1105/ZOJ 1150 S-Trees(用数组模拟二叉树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

712 - S-Trees

Time limit: 3.000 seconds

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=653

http://poj.org/problem?id=1105

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1150

A Strange Tree (S-tree) over the variable set $X_n = \{x_1, x_2, \dots, x_n\}$ is a binary tree representing a Boolean function $f: \{0, 1\}^n \rightarrow \{ 0, 1\}$. Each path of the S-tree begins at theroot node and consists of n+1 nodes. Each of the S-tree's nodes has a depth, which is the amount of nodes between itself and the root (so the root has depth 0). The nodes with depth less than n are called non-terminal nodes. All non-terminal nodes have two children: the right child and the left child. Each non-terminal node is marked with some variable xi from the variable set Xn. All non-terminal nodes with the same depth are marked with the same variable, and non-terminal nodes with different depth are marked with different variables. So, there is a unique variable xi1 corresponding to the root, a unique variable xi2 corresponding to the nodes with depth 1, and so on. The sequence of the variables $x_{i_1}, x_{i_2}, \dots, x_{i_n}$ is called the variable ordering. The nodes having depth n are called terminal nodes. They have no children and are marked with either 0 or 1. Note that the variable ordering and the distribution of 0's and 1's on terminal nodes are sufficient to completely describe an S-tree.

As stated earlier, each S-tree represents a Boolean function f. If you have an S-tree and values for the variables $x_1, x_2, \dots, x_n$, then it is quite simple to find out what$f(x_1, x_2, \dots, x_n)$ is: start with the root. Now repeat the following: if the node you are at is labelled with a variable xi, then depending on whether the value of the variable is 1 or 0, you go its right or left child, respectively. Once you reach a terminal node, its label gives the value of the function.

Figure 1: S-trees for the function $x_1 \wedge (x_2 \vee x_3)$

On the picture, two S-trees representing the same Boolean function,$f(x_1, x_2, x_3) = x_1 \wedge (x_2 \vee x_3)$, are shown. For the left tree, the variable ordering is x1x2,x3, and for the right tree it is x3x1x2.

The values of the variables $x_1, x_2, \dots, x_n$, are given as a Variable Values Assignment(VVA) 

\begin{displaymath}(x_1 = b_1, x_2 = b_2, \dots, x_n = b_n)\end{displaymath}

with  $b_1, b_2, \dots, b_n \in \{0,1\}$ . For instance, (  x 1  = 1,  x 2  = 1  x 3  = 0) would be a valid VVA form  = 3, resulting for the sample function above in the value  $f(1, 1, 0) = 1 \wedge (1 \vee 0) = 1$ . The corresponding paths are shown bold in the picture.

Your task is to write a program which takes an S-tree and some VVAs and computes$f(x_1, x_2, \dots, x_n)$ as described above.

Input 

The input file contains the description of several S-trees with associated VVAs which you have to process. Each description begins with a line containing a single integer n $1 \le n \le 7$ , the depth of the S-tree. This is followed by a line describing the variable ordering of the S-tree. The format of that line is  x i 1   x i 2  ... x i n . (There will be exactly  n  different space-separated strings). So, for  n  = 3 and the variable ordering  x 3 x 1 x 2 , this line would look as follows:

x3 x1 x2

In the next line the distribution of 0's and 1's over the terminal nodes is given. There will be exactly 2n characters (each of which can be 0 or 1), followed by the new-line character. The characters are given in the order in which they appear in the S-tree, the first character corresponds to the leftmost terminal node of the S-tree, the last one to its rightmost terminal node.

The next line contains a single integer m, the number of VVAs, followed by m lines describing them. Each of the m lines contains exactly n characters (each of which can be 0 or 1), followed by a new-line character. Regardless of the variable ordering of the S-tree, the first character always describes the value of x1, the second character describes the value of x2, and so on. So, the line

110

corresponds to the VVA ( x1 = 1, x2 = 1, x3 = 0).

The input is terminated by a test case starting with n = 0. This test case should not be processed.

Output 

For each S-tree, output the line `` S-Tree # j : ", where  j  is the number of the S-tree. Then print a line that contains the value of  $f(x_1, x_2, \dots, x_n)$  for each of the given  m VVAs, where  f  is the function defined by the S-tree.

Output a blank line after each test case.

Sample Input 

3
x1 x2 x3
00000111
4
000
010
111
110
3
x3 x1 x2
00010011
4
000
010
111
110
0

Sample Output 

S-Tree #1:
0011S-Tree #2:
0011

英语阅读题=v=:

注意:Depending on whether the value of the variable is 1 or 0, you go its right or left child

变量为1,去右孩子;变量为0,去左孩子。


思路:

建一个二叉树或用数组也行。

(由于数据范围较小:n<=7,这里用数组要好些)


完整代码:(太慢了,没到0ms)

/*UVaOJ: 0.016s*/
/*POJ: 16ms,144KB*/
/*ZOJ: 0ms,180KB*/#include<cstdio>
#include<cstring>
using namespace std;
int serial[7];
char ch[1<<7],temp[7];int main()
{int cas = 1;while (true){int n, t, size;scanf("%d", &n);if (!n)break;getchar();//别忘了读去'\n'//读取x3 x1 x2这样的getchar();for (int i = 0; i < n - 1; i++){scanf("%d", &serial[i]);--serial[i];//这里要减一getchar();getchar();}scanf("%d", &serial[n - 1]);--serial[n - 1];getchar();//别忘了读去'\n'//读取00010011size = 1 << n;for (int i = 0; i < size; i++)ch[i] = getchar();printf("S-Tree #%d:\n", cas++);scanf("%d", &t);getchar();//别忘了读去'\n'while (t--){for (int i = 0; i < n; i++)temp[i] = getchar();getchar();//别忘了读去'\n'int l = 0, r = size, m = size >> 1;for (int i = 0; i < n; i++){if (temp[serial[i]] == '0')r = m;elsel = m;m = (l + r) >> 1;}printf("%c", ch[l]);}printf("\n\n");}return 0;
}

Source

Mid-Central European Regional Contest 1999

这篇关于UVa 712/POJ 1105/ZOJ 1150 S-Trees(用数组模拟二叉树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/777807

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

uva 10055 uva 10071 uva 10300(水题两三道)

情歌两三首,水题两三道。 好久没敲代码了为暑假大作战热热身。 uva 10055 Hashmat the Brave Warrior 求俩数相减。 两个debug的地方,一个是longlong,一个是输入顺序。 代码: #include<stdio.h>int main(){long long a, b;//debugwhile(scanf("%lld%lld", &

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];