【GESP】2024年12月6级 树上游走

题目描述

小杨有一棵包含无穷节点的二叉树(即每个节点都有左儿子节点和右儿子节点;除根节点外,每个节点都有父节点),其中根节点的编号为1,对于节点i,其左儿子的编号为2×i,右儿子的编号为2×i+1。
小杨会从节点s开始在二叉树上移动,每次移动为以下三种移动方式的任意一种:

  1. 第1种移动方式: 如果当前节点存在父亲节点,向上移动到当前节点的父亲节点,否则不移动;
  2. 第2种移动方式:移动到当前节点的左儿子;
  3. 第3种移动方式:移动到当前节点的右儿子。

小杨想知道移动n次后自己所处的节点编号。数据保证最后所处的节点编号不超过 1012

输入格式

第一行包含正整数n,s。

第二行包含一个长度为n且包含大写字母U R L的字符串,代表每次移动的方式,U代表第一种,L代表第二种方式,R代表第三种。

输出格式

输出一个正整数,代表最后所处的节点编号。

样例 #1

样例输入 #1

3 2
URR

样例输出 #1

7

提示

小杨的移动路线为 2 → 1 → 3 → 7。

子任务编号数据点占比ns
120%≤ 10≤ 2
220%≤ 50≤ 10
360%≤ 106≤ 1012

对于全部数据,保证有 1 ≤ n ≤ 1061 ≤ s ≤ 1012

解题思路

定义

int t=0;//对应的层数
long long n,s;//移动次数与初始节点
string ss;//输入的字符串

输入

cin>>n>>s;
cin>>ss;

计算

for(int i=0;i<n;i++){
	string a;
	a=ss[i];
	if(a=="U"){//第1种移动方式
		if(s==1)continue;//节点为根节点,直接跳过
		if(t){//层数大与0,将层数减1
			t--;
			continue;
		}
		s/=2;//以上均不符合,则直接除以2
	}
	else if(a=="L"){//第2种移动方式
		if(s*2>1e12)t++;//超过10的12次方,将层数加1
	    else s*=2;//否则直接乘2
	}
	else if(a=="R"){//第3种移动方式
		if(s*2+1>1e12)t++;//超过10的12次方,将层数加1
	    else s=s*2+1;//否则直接乘2在加1
	} 
}

输出

cout<<s;

代码

#include <bits/stdc++.h>
using namespace std;
int main(){
	int t=0;
	long long n,s;
    string ss;
	cin>>n>>s;
    cin>>ss;
	for(int i=0;i<n;i++){
		string a;
		a=ss[i];
		if(a=="U"){
			if(s==1)continue;
			if(t){
				t--;
				continue;
			}
			s/=2;
		}
		else if(a=="L"){
			if(s*2>1e12)t++;
            else s*=2;
		}
		else if(a=="R"){
			if(s*2+1>1e12)t++;
            else s=s*2+1;
		}
	} 
	cout<<s;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值