lca

题意:在完全二叉树中,给两个结点的位置,求出它们最近的公共祖先(lca),输入为十六进制,输出为十六进制。

思路:表面是lca,实际是二进制的题目。比如5和9它们的lca是2。5的二进制101、9的二进制1001;它们最长公共前缀是10,也就是2。再加上16进制和2进制可以直接换算,所以我们出一下边角问题就可以直接得到lca。复杂度就是输入数据的长度。

代码:我写了个贼暴力的解法。慢慢继续学习更优解法吧。

#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],a1[4000],b1[4000],c[4000];
int main()
{
	int t,i,j,k,temp;
	string str1,str2;
	cin>>t;
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(a1,0,sizeof(a1));
		memset(b1,0,sizeof(b1));
		memset(c,0,sizeof(c));
		cin>>str1>>str2;
		int len1=str1.size(),len2=str2.size();
		for(i=0;i<len1;i++)//字符串存到数字数组里,方便进制转换 
		{
			if(str1[i]>='a'&&str1[i]<='f')
			a[i]=(str1[i]-'a')+10;
			else if(str1[i]>='0'&&str1[i]<='9') 
			a[i]=int(str1[i]-'0');
		}
		for(i=0;i<len2;i++)
		{
			if(str2[i]>='a'&&str2[i]<='f')
			b[i]=(str2[i]-'a')+10;
			else if(str2[i]>='0'&&str2[i]<='9') 
			b[i]=int(str2[i]-'0');
		}
		for(i=0;i<len1;i++)//16进制转二进制 
		{
			j=(i+1)*4;
			temp=0;
			while(a[i]!=0)
			{
				a1[j]=a[i]%2;
				a[i]=a[i]/2;
				j--;
				temp++;
			}
			while(temp<4)
			{
				a1[j]=0;
				j--;
				temp++;
			}
		}
		for(i=0;i<len2;i++)
		{
			j=(i+1)*4;
			temp=0;
			while(b[i]!=0)
			{
				b1[j]=b[i]%2;
				b[i]=b[i]/2;
				j--;
				temp++;
			}
			while(temp<4)
			{
				b1[j]=0;
				j--;
				temp++;
			}
		}
		len1=len1*4,len2=len2*4;
		
		k=0;
		i=1,j=1;
		//存最长公共前缀 
		while(a1[i]==0)
			i++;
		while(b1[j]==0)
		    j++;
		for(;i<=len1&&j<=len2;i++,j++)
		{
			if(a1[i]==b1[j])
			{
				c[k]=a1[i];
			     k++;
			}
			else
			break;
			
		} 
		//转十六进制 
		int num=0,f=0;
		char ch[1000],sh='a';
		for(i=k-1;i>=0;)
		{
			num=0;
			temp=4;
			while(temp--)
			{
				num+=c[i]*pow(2,3-temp);
				i--;
			}
			if(num>=10)
			ch[f]=sh+(num-10);
			else
			ch[f]=num+48;
			f++;
		}
	//输出数据 
	for(i=f-1;i>=0;i--)
	cout<<ch[i];
	cout<<endl;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值