欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UVA - 712 S-Trees

程序员文章站 2024-03-18 22:12:04
...
/*
  这题初看时容易被吓到,甚至连题目的意思都有些一知半解,但是沉下心仔细看几遍,就能发现也不是那么难,肯定不是难到完全想不出那种
  
  这题主要就是在考察完全二叉树
  
  收获:
  1. C 语言的格式控制非常好用,可以把一个已知位数的整数,其位数一步步分离出来,链接见 
  https://zhidao.baidu.com/question/493600982.html?qbl=relate_question_0&word=scanf%20%25nd
  
  但是如果想在C++中用呢?如果不用scanf的格式控制呢?
  我也在网上搜到了解决方法,见下个链接(该链接针对 char型数组):
  https://zhidao.baidu.com/question/1882344941428175148.html
  
  但是对于string类呢?
  对于string的话,我觉得可以采用 substr,不过string的函数总是会慢一些,毕竟 STL 很可能成为性能瓶颈
  
  所以,综上所述...其实还是用scanf的格式控制最优了!~ 写法简洁,还不容易出错!→_→
  

*/


/*
  查阅过的有关链接:
  1、 完全二叉树,二叉树及其相关:
  https://www.zhihu.com/question/19809666 
  (
    这个链接提到了一个很有意思的问题,不同的书,对几种经典二叉树的定义,居然都是有区别的。我的一点小感受就是:
    如果要考研,务必将要考的学校的教材买来看看,说不定,他们的专业教材里,对于二叉树的相关类型术语,和我们自己用的专业书里,是完全不同的,这样做题时,可不就尴尬了,必错无疑啊!~
  )
  
  http://www.cnblogs.com/lxw0109/p/binary-tree.html
  //给出了简明的定义
  
  http://www.cnblogs.com/idorax/p/6441043.html
  //非常详细,想仔细弄懂应该看这个
  
  
  
  2、该题的题解:
  http://www.cnblogs.com/cute/p/3639970.html
  http://www.cnblogs.com/zyb993963526/p/6240125.html
  
  3、C语言格式控制之 %nd 控制整数位数
  %d是按照十进制整数形式输出,%nd中的n表示有效数字的位数;
  https://zhidao.baidu.com/question/493600982.html?qbl=relate_question_0&word=scanf%20%25nd
  
  https://zhidao.baidu.com/question/1882344941428175148.html
  
*/


//法一
#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#define rep(i, n) for ( int i = 0; i < (n); i++ )
using namespace std;

int n, m, pos[1 << 10], x, s[1 << 10];

int main ()
{
	int kase = 0;
	while ( cin >> n && n )
	{
		string str;
		getchar(); //吃掉数字 n 后面的空格
		getline(cin, str); // 第二行数据是无用的,不影响输出结果,所以用 getline 吃掉就行了 
		
		rep(i, pow(2, n))
		scanf("%1d", pos + i);
		//pos数组存所有叶子节点里的数据
		
		cin >> m;
		int t = 0;
		
		rep(i, m)
		{
			int l = 1; //l=1表示从根节点开始走
			rep(j, n)
			{
				scanf("%1d", &x);
				l = l * 2 + x;
			} //x取0时表示向左走,x取1时表示向右左;因为节点i的左孩子的节点为 2i,右孩子的节点为 2i+1,有 l = l * 2 + x;
			l = l - pow(2, n); //这是为了找到,当前查询到的叶子,在pos数组中的下标,然后将该位置里的值赋给s数组
			s[t++] = pos[l];	
		}
		
		cout << "S-Tree #" << ++kase << ":" << endl;
		rep(i, m)
		cout << s[i]; //最后将找到的所有叶子里的值一起输出即可
		
		cout << endl << endl;
	}
	return 0;
}


//法二
//其实这题,自己多举几个例子,按照题意走几遍,就会发现:其实题目结果,只关乎于每一步是向左还是向右,和 x1 x2 x3 究竟以怎样的顺序排列,毫无关系
//所以,每次输入的 "x1 x2 x3..."这行数据其实是干扰数据,这个我也是用了一段时间才发现 T^T

#include <iostream>
#include <string>
#define rep(i, n) for ( int i = 0; i < (n); i++ )
using namespace std;

const int N = 10;
int n;
string leaves;

int solve ( const string& s )
{
	int u = 1;
	rep(i, n)
	{
		if (s[i] == '0') u = u * 2;
		else u = u * 2 + 1;
	}
	return leaves[u - (1 << n)] - '0';
}

int main()
{
	int kase = 0;
	while (cin >> n && n)
	{
		string s;
		cout << "S-Tree #" << ++kase << ":\n";
		
		rep(i, n) cin >> s;
		
		int m;
		cin >> leaves >> m;
		while (m--)
		{
			string str;
			cin >> str;
			cout << solve (str);
		}
		cout << endl << endl;
		
	}
}


一点题外话:

  眼下终于没有那么忙乱了,剩下的课内的作业和附加作业,和要看的教案什么的,只要每天写一点,还是能保证写完的...

  所以,我终于能够回来继续敲 uva 的题目啦,哈哈哈哈哈!~o(* ̄▽ ̄*)ブ