pat-1151

值的二刷 

#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循环里的下一组导致根本没用上(注意 )

英语

问题

一些小细节的东西都要再总结 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值