原题描述:
时间:1s 空间:256M
题目描述:
小信在玩跳房子游戏,已知跳房子游戏的图表现为一颗完美的具有个节点的二叉树。从根节点依次编号为。节点的左子节点编号为,右子节点编号为。
小信从从节点出发,共跳步,用一个长度为的字符串表示小信的移动方向,“U”表示跳到当前所在节点的父节点,“L”表示跳到当前节点的左子节点,“R”表示跳到当前节点的右子节点。
输出小信在跳了步之后所处的节点编号,保证最终答案不超过。
提示:在跳的过程中节点编号可能超过。
输入格式:
第一行包含两个整数,表示小信移动次数和初始所在节点编号。
第二行包含一个只含“U”,“L”和“R”的长为的字符串。
输出格式:
输出一个整数,表示小信在跳了步之后所处的节点编号。
样例1输入:
3 2
URL
样例1输出:
6
样例2输入:
6 500000000000000000
RRRUUU
样例2输出:
500000000000000000
约定与提示:
对于100%的数据,,
样例1:小信的移动路径是2 -> 1 -> 3 -> 6
题目大意:
有一个人,再完全二叉树的x节点,求他跳动n此后在哪个节点,给定每次怎么跳动。
主要思路:
这个题是用硬枚举,但枚举时会爆掉,有人说用__int128,但还是爆,所以要消除一些无用操作(题目保证结果<=)
当操作是U时,我们发现x = x/2(向下取整,long long 自动向下取整)
当操作是R时,我们发现x = x*2+1
当操作是L时,我们发现x = x*2
我们发现LU,RU这些操作组可以不执行。
LU:
RU:
我们用一个vector<char>(设为v)记录一下操作的过程。
当v.back() 不是U且v非空且当前插入进来的字符是U,那么就可以抵消,把v.back删掉(由于插入时是push_back(),所以上一个插入的是在最尾端,就是v.back() )。
否则就插入一个操作符。
这样就不会爆了。
最后遍历一遍v,根据题目要求操作就可以了。
注意事项:
- 一定要开long long。
- UL和UR是不能抵消的,具体请看下图。
代码code:
#include<bits/stdc++.h>
using namespace std;
long long n,x;//开long long
vector<char> st;
int main()
{
cin>>n>>x;
string s;
cin>>s;
for(int i=0;i<n;i++)
{
if(s[i] == 'U'&&!st.empty()&&st.back()!='U')//如果可以抵消
{
st.pop_back();
}
else
{
st.push_back(s[i]);
}
}
for(int i=0;i<st.size();i++)//开始操作
{
if(st[i] == 'U')
{
x = x/2;
}
else if(st[i] == 'L')
{
x*=2;
}
else
{
x*=2;
x++;
}
}
cout<<x;
return 0;
}