一个策略树(S-tree)是一组变量Xn={x1,x2...xn}的表现形式,
它代表一个布尔函数f:{0,1}n->{0,1},策略树每条路径从根结点开始由n+1个结点组成,
策略树的每一个结点都有一个深度,
结点的深度等于当前结点到根结点之间的结点总和(根节点的深度等于0),
结点深度小于n的结点叫做非终止结点,所有的非终止结点都有俩个孩子,左孩子和右孩子,
每个非终止结点被xi标志(xi来自Xn集合),
所有深度一样的非终止结点被一样的xi标志,
所有深度不一样的非终止结点被不一样的xi标志,所以根结点由独特的xi1变量标志,
独特的xi2变量标志深度等于1的结点,一直下去.xi1,xi2....xin叫做变量顺序,
请注意,变量顺序和分布在终止结点上的0和1有效的描述了一颗策略树.
在先前的说明中,每一颗策略树代表了一个布尔函数f,如果你有一颗策略树和变量x1....xn的值,你可以非常简单的算出f(x1....xn)的结果
计算方法如下
从根结点开始,重复使用一下方法:如果结点标记为xi,这个变量的值是0还是1决定你是往左孩子走还是右孩子走,
一旦你到达一个终止结点,当前的函数值就等于当前的终止结点的值
在图片里,俩个策略树代表相同的布尔函数f(x1,x2,x3)=x1^(x2vx3),正如我们展示的那样,左边的变量顺序是x1,x2,x3,右边的是x3,x1,x2
变量x1.....xn的值,如下声明变量的值(VVA)
(x1=b1,x2=b2.......xn=bn)
b1,b2....属于{0,1},我们如下给变量赋值
(x1=1,x2=1,x3=0)是一个合法的VVA,此时n=3,这样将产生同样的函数f(1,1,0)=1^(1 v 0),在图中用粗黑线描出,注意,0往左走,1往右走
你的任务是写一个程序,拿到一颗策略树和VVA,计算f(x1,x2.....xn)
输入
输入文件的组成描述了几组策略树和相关联的VVA,每一个描述第一行由一个单独的int值n组成,1<=n<=7,代表当前策略树的深度,
随下来的行描述策略树的变量顺序,格式:xi1.....xin(由空格隔开的不同的明确的n),
所以,假如n=3,变量顺序x3,x1,x2,这行就像下面那样
x3 x1 x2
下一行由0和1组成代表终止结点,明确的2^n个字符(每一个要么是0要么是1),最左边是最左结点,最右是最右结点(注意,策略树是满二叉树,第n层有2^n个结点)
下一行由一个单独的int类型m组成,代表VVA的数量,在随下来的m行描述它们,每一行包含n个(0或1)字符,
不管策略树的变量顺序,第一个字符总是描述x1,第二个字符描述x2,所以如下面的行
110
组成VVA(x1=1,x2=1,x3=0)
输入结束标志n=0
输出
对每一个策略树,输出一行"S-Tree #j:",j是策略树的序号,然后输出一行,对给定的m个VVA,输出f(x1....xn)的值
AC:0ms
#include <iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int main()
{
int n;
int T = 1;
while (cin >> n)
{
if(n == 0)
return 0;
cout << "S-Tree #" << T << ":" << endl;
T++;
//叶子结点个数2^n
//前面几层总和是2^n-1
//
int num = pow(2, n);
int preNum = num - 1;
char* a = new char[num];
//叶子结点实际位置tIndex-preNum
string str;
getline(cin, str);
getline(cin, str);
for(int i = 0; i < num; i++)
{
cin >> a[i];
}
int m;
cin >> m;
for(int i = 0; i < m; i++)
{
char c;
int index = 0;
for(int j = 0; j < n; j++)
{
cin >> c;
if(c == '0')
{
index = 2 * index + 1;
}
else
{
index = 2 * index + 2;
}
}
cout << a[index - preNum];
}
cout << endl;
cout << endl;
}
return 0;
}