题目描述
小杨有一棵包含无穷节点的二叉树(即每个节点都有左儿子节点和右儿子节点;除根节点外,每个节点都有父节点),其中根节点的编号为1,对于节点i,其左儿子的编号为2×i,右儿子的编号为2×i+1。
小杨会从节点s开始在二叉树上移动,每次移动为以下三种移动方式的任意一种:
- 第1种移动方式: 如果当前节点存在父亲节点,向上移动到当前节点的父亲节点,否则不移动;
- 第2种移动方式:移动到当前节点的左儿子;
- 第3种移动方式:移动到当前节点的右儿子。
小杨想知道移动n次后自己所处的节点编号。数据保证最后所处的节点编号不超过 1012。
输入格式
第一行包含正整数n,s。
第二行包含一个长度为n且包含大写字母U R L的字符串,代表每次移动的方式,U代表第一种,L代表第二种方式,R代表第三种。
输出格式
输出一个正整数,代表最后所处的节点编号。
样例 #1
样例输入 #1
3 2
URR
样例输出 #1
7
提示
小杨的移动路线为 2 → 1 → 3 → 7。
子任务编号 | 数据点占比 | n | s |
---|---|---|---|
1 | 20% | ≤ 10 | ≤ 2 |
2 | 20% | ≤ 50 | ≤ 10 |
3 | 60% | ≤ 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;
}