NC16692 [NOIP2001]求先序排列
题目链接
关键点:
1、已知中序和后序遍历,首先明确中序遍历是左根右,后序为左右根,先序为根左右,那么求根可以直接从后序的最后一位来找,然后在中序里找到该根(位置为pos),那么该pos的前面就为左子树,后面就为右子树,再以此类推
2、设中序(pl,pr)后序(sl,sr)左子树为
(pl,pos-1,sl,x)x-sl = pos-1-pl ---------- x = pos-1-pl+sl;
左子树为(pl, pos-1, sl, pos-1-pl+sl)
同理右子树
find(pos+1, pr, pos-pl+sl, sr-1);
2、且无论是在左子树还是右子树,pl和pr的相差越来越近,因此有可能pl>pr,这是不存在的,因此在最开始要判断返回
完整代码:
# include <cstdio>
# include <iostream>
using namespace std;
string zhong, hou;
void find(int lz, int rz, int lh, int zh)
{
if (lz>rz)
return ;
char root = hou[zh];
cout<<root;
int i;
for (i=lz; i<=rz; i++)
{
if (zhong[i] == root)
break;
}
find(lz, i-1, lh, i-lz+lh-1);
find(i+1, rz, i-lz+lh, zh-1);
}
int main()
{
cin>>zhong>>hou;
int lz = 0, rz = zhong.size()-1, lh = 0, zh = hou.size()-1;
find(lz, rz, lh, zh);
return 0;
}
NC204382 中序序列
题目链接
关键点
1、一样的思路,首先先序为根左右,后序为左右根,中序为左根右,且在先序中左里又可以分成根左右,然后再继续,直到只剩下一个结点,且该结点就为左节点,那么左子树的根为先序的第二个,然后再到后序里去找这个根(pos),后序里的左又可以分成左右根左右根,那么找到了左子树的根,即找到了后序里的左子树的最后
2、先序(pl, pr), 后序(sl, sr),那么左子树 deal(pl+1, x, sl, pos) x-pl-1 = pos-sl
x = pos-sl+pl+1;
同理右子树deal (x+1, pr, pos+1, sr-1)
同样的,还是得判断区间是否存在
完整代码
vector<int>v;
class Solution {
public:
void deal(int pr, int pl, int sr, int sl, vector<int> &pre, vector<int> &suf)
{
if (pr==pl)
{
v.push_back(pre[pr]);
return ;
}
int x = pre[pr+1];
int pos = -1;
for (int i=sr; i<=sl; i++)
{
if (suf[i]==x)
{
pos = i;
break;
}
}
deal(pr+1, pr+1+pos-sr, sr, pos, pre, suf);
v.push_back(pre[pr]);
if (sl-1>=pos+1)deal(pr+1+pos-sr+1, pl, pos+1, sl-1, pre, suf);
}
vector<int> solve(int n, vector<int>& pre, vector<int>& suf) {
deal(0, pre.size()-1, 0, suf.size()-1, pre, suf);
return v;
}
};
NC23046 华华教月月做数学
题目链接
关键点
1、快速幂和快速乘,快速幂是将次方分成二进制数,而快速乘将一个乘数分成二进制数(看成n个m相加)
完整代码:
# include <cstdio>
# include <iostream>
using namespace std;
typedef long long ll;
int t;
ll a, b, p;
ll cheng(ll x, ll y)
{
ll base = x%p;
ll ans = 0;
while (y)
{
if (y&1)
ans = (ans+base)%p;
base = (base+base)%p;
y>>=1;
}
return ans;
}
ll mi()
{
ll ans = 1;
ll base = a%p;
while (b)
{
if (b&1)
ans = cheng(ans, base)%p;
base = cheng(base, base)%p;
b>>=1;
}
return ans;
}
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld%lld", &a, &b, &p);
cout<<mi()<<endl;
}
return 0;
}