值的二刷
#include<iostream>
#include<vector>
#include<map>
//少了这句话会出现如下错误
//using namespace std; (注意)
using namespace std;
int m,n;
vector<int> in,pre;
map<int,int> pos;
//此时中序刚好可以直接用左右i的序号就可以左右分开
//preroot 前序根节点 inll中序的左范围 inrr中序的右范围 a,b,待寻找的公共先祖的序号
void lca(int preroot,int inll,int inrr,int a,int b)
{ //end 打上了忘写终止条件 决定以后检查时若写了终止条件则将end->END
if(inll>inrr) return;
//可以直接使用map找到根在中序中的的位置
//不能在这里改因为这里适合下面对应的
//调用答案库时最好对应起来不要出现交错索引的情况
int root=pos[pre[preroot]] ;
int inroot=in[root];
//此时都在左子树
//需要在同一级上都在pos上
if(pos[a]<root&&pos[b]<root)
lca(preroot+1,inll,root-1,a,b);
//两种情况在左在右都可以
if((pos[a]<root&&pos[b]>root)||(pos[a]>root&&pos[b]<root))
// LCA of U and V is A. i 还有一个小点注意哦
//没加换行(注意)
printf("LCA of %d and %d is %d.\n",a,b,inroot);
//注意这里必须加else否则有一个测试点会不过 应该是a,与b相等时会有两个答案,当给出的数据有可能本身重合是看看要不要加if else(注意)
else if(pos[a]>root&&pos[b]>root)
lca(preroot+root-inll+1,root+1,inrr,a,b);
else if(pos[a]==root)
//X is an ancestor of Y.
printf("%d is an ancestor of %d.\n",a,b);
else if(pos[b]==root)
printf("%d is an ancestor of %d.\n",b,a);
}
int main()
{ int p1,p2;
cin>>m>>n;
//有一个0位置没用到
in.resize(n+1) ;
pre.resize(n+1);
for(int i=1;i<=n;i++)
{
int temp;
cin>>temp;
//这里序号从0开始而键值从1开始导致不对应差1 ,为了和键值对对应最好用resize(注意)
in[i]=temp;
//建立键值对
pos[temp]=i;
}
for(int i=1;i<=n;i++)
{
int temp1;
cin>>temp1;
//此处也不对应
pre[i]=temp1;
}
for(int i=0;i<m;i++)
{
cin>>p1>>p2;
//map会将没有的键值返回为0
//键值不存在会返回0所以要从1开始赋值不能和不存在的键值重合(注意)
if(pos[p1]==0&&pos[p2]==0)
//ERROR: U and V are not found.
printf("ERROR: %d and %d are not found.\n",p1,p2);
//必须择一否则会出现两个if同时成立出现错误
else if(pos[p1]==0||pos[p2]==0)
//ERROR: U is not found.
//错误一开始只写了p1导致错误
//最后的换行键都没打 一看题干有换行立即打上(注意)
//可以最后出现输入输出交杂即输入一个处理一个 他只看输出(注意)
printf("ERROR: %d is not found.\n",pos[p1]==0?p1:p2);
//位置放错处理一组数据,就输出一组,必须放在for循环里面放在外面程序会直接执行for循环里的下一组导致根本没用上()注意
if(pos[p1]!=0&&pos[p2]!=0)
{ //lca(int preroot,int inll,int inrr,int a,int b)
lca(1,1,n,p1,p2);
}
}
return 0;
}
总结
1./少了这句话会出现如下错误 vctor does‘n name atype
//using namespace std; (注意)
2./此时中序刚好可以直接用左右i的序号就可以左右分开 键值対的应用 针对中序
3. //end 打上了忘写终止条件 决定以后检查时若写了终止条件则将end->END
4.//可以直接使用map找到根在中序中的的位置 有了键值対就用不着 while了
5.//调用答案库时最好对应起来不要出现交错索引的情况 最好直接弄成 hash直接映射类型的x->y
6.//需要在同一级上都在pos上
7.//两种情况在左在右都可以 或者不能少写
8.//注意这里必须加else否则有一个测试点会不过 应该是a,与b相等时会有两个答案,当给出的数据有可能本身重合是看看要不要加if else(注意)
9.//没加换行(注意)见到题目换行一定要换行,他不会明确告诉你,你要自己看
10.//有一个0位置没用到
in.resize(n+1) ; 下标从1开始
11.//这里序号从0开始而键值从1开始导致不对应差1 ,为了和键值对对应最好用resize(注意)
12. //map会将没有的键值返回为0
//键值不存在会返回0所以要从1开始赋值不能和不存在的键值重合(注意) 0此时为边界条件不能和其重合
13. //可以最后出现输入输出交杂即输入一个处理一个 他只看输出(注意)
14.//位置放错处理一组数据,就输出一组,必须放在for循环里面放在外面程序会直接执行for循环里的下一组导致根本没用上(注意 )
英语
问题
一些小细节的东西都要再总结