数据结构刷题记

Poj 3437 类似于多叉树转化为二叉树

【题意】把多叉树转化为二叉树,和原来相比高度变化了多少
【题解】原来的高度就是原来最多有连续的多少条边,二叉树的高度是按照原来的树的构思每一条路径最长的那一个

# include <bits/stdc++.h>
using namespace std;

int h1=0,h2=0,i=-1;
string s;
void dfs(int c,int j)
{
	int nowj=0;
	while(s[++i]=='d'){
		nowj++;
		dfs(c+1,j+nowj);
	}
	h1=max(h1,c);
	h2=max(h2,j); 
}
int main()
{
	int cass=0;
	while(cin>>s){
		if(s=="#") break;
		dfs(0,0);
		cout<<"Tree "<<++cass<<": "<<h1<<" => "<<h2<<endl;
		h1=0,h2=0,i=-1;
	}
	
	return 0;
}
/*
dudduduudu
ddddduuuuu
dddduduuuu
dddduuduuu
#
*/

Poj 2499 计算二叉树的路径

【题意】一棵二叉树从(1,1)这个对开始,根节点(a,b)左儿子(a+b,b),右儿子(a,a+b),给定一个对,问往左右分别走了多少次
【题解】逆向思维,大的那一个是由小的那一个加起来的,所以只要每次比较一下是谁大,然后那一边的加上倍数,然后那一边的变成余数就可以了

# include <bits/stdc++.h>
using namespace std;

int main()
{
	int q;
	int cass=0;
	scanf("%d",&q);
	while(q--){
		int i,j;
		int l=0,r=0;
		scanf("%d%d",&i,&j);
		i=i,j=j;
		while(i!=1&&j!=1){
			if(i>j){
				int d=i/j;
				l+=d;
				i=i%j;
			}else if(i<j){
				int d=j/i;
				r+=d;
				j=j%i;
			}
			//cout<<i<<" "<<j<<endl;
		}
		if(i>1) l+=(i-1);
		if(j>1) r+=(j-1);
		printf("Scenario #%d:\n",++cass);
		printf("%d %d\n\n",l,r);
	}
	
	return 0;
}
/*
3
42 1
3 4
17 73
*/

Poj 1145 二叉树的遍历

【题意】给你一棵二叉树的先序遍历过程,让你还原二叉树,并求出路径长度是否有给定的那个值
【题解】首先把那一个数读进来,然后一直读直到读到左括号,然后再读一个,如果读到的是右括号那么就说明当前节点就是叶子节点,返回-1;如果不是那么应该是数字,那么把当前的字符返回给缓冲区,然后按照数值的形式把该值读进来,然后让原来想要查找的数减去当前的数,然后再求一遍,那么先进行的一定是左子树(自行理解一下),然后再是右子树,然后把还没有读完的剩下的右括号读完,判断如果是叶子节点且数值一致的话,那么返回1,或者该节点的左子树或右子树是符合的话,返回1;否则返回0。

# include<bits/stdc++.h> 
using namespace std;

int RiseTree(int s)
{
	char c;
	int v;
	scanf("%c",&c);
	while(c!='(') scanf("%c",&c);
	c=getchar();
	while(c==' '||c=='\n') c=getchar();
	if(c!=')'){
		ungetc(c,stdin);
		/*
		ungetc是将读出的数据再次放回到缓冲区,下一次读数据是,会再次读出来
		不过如果把独处的数据放回到缓冲区去后,没有将缓冲区的数据读出来
		就再次试图把读出来的数据放回到缓冲区去——数据是放不进去的
		(可以把缓冲区看做一个可变化的容器,当你把试图用ungetc()函数把读出的数据放回缓冲区,
		缓冲区这个容器就为这些数据分配相应的大小空间,之后这个空间是不变的,
		直到你把缓冲区的数据读出去,所以你在没有释放缓冲区时,再想往缓冲区装数据是装不进去的) 
		*/
		scanf("%d",&v);
	}else return -2;//说明是叶子节点 
	int Lf=RiseTree(s-v);//用相减等于0的方式证明相等 
	int Rf=RiseTree(s-v);
	while((c=getchar())!=')');
	if(Rf==-2&&Lf==-2&&s==v) return 1;//如果是叶子节点而且数据相等 
	else if(Rf==1||Lf==1) return 1;//有一个节点成立那么就是成立的 
	else return 0;//不成立 
}
int main()
{
	int num;
	while(~scanf("%d",&num)){
		if(RiseTree(num)==1) printf("yes\n");
		else printf("no\n");
	}
	return 0;
}
/*
22 (5(4(11(7()())(2()()))()) (8(13()())(4()(1()()))))
20 (5(4(11(7()())(2()()))()) (8(13()())(4()(1()()))))
10 (3 
     (2 (4 () () )
        (8 () () ) )
     (1 (6 () () )
        (4 () () ) ) )
5 ()
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值