注意:poj上的数据与zoj不同,第二处输入没有逗号 ' , '
题意:输出测试用例中是最近公共祖先的节点,以及这个节点作为最近公共祖先的次数。
思路:直接求,两个节点一直往上爬,知道爬到同一个节点,这个节点即为最近公共祖先。
这道题的输入挺······,空格可以随意输入。Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.
5 : ( 3 )
scanf("%d%1s%1s%d%1s",&fa,s1,s2,&m,s3); //第一处输入, s1为":" s2为"(" s3为")"。
(2,3)
scanf("%1s%d%1s%d%1s",s1,&a,s2,&b,s3); //第二处输入, s1为"(" s2为"," s3为")"。
%1s读取一个字符
#include<iostream> #include<cstring> #include<stdio.h> using namespace std; const int N=1000; int f[N];// int sum[N];//记录次数 int depth(int x){//计算层数 int dep=0; while(x!=-1){ x=f[x]; dep++; } return dep; } int main(){ char s1[10],s2[10],s3[10]; int n; char c; while(scanf("%d",&n)!=EOF){//树的节点个数 memset(f,-1,sizeof(f)); memset(sum,0,sizeof(sum)); int tempn=n; while(n--){ int fa,so; int m; scanf("%d%1s%1s%d%1s",&fa,s1,s2,&m,s3); //注意输入!!! while(m--){ scanf("%d",&so); f[so-1]=fa-1; } } int i; for(i=0;f[i]>=0;i++); int n2; scanf("%d",&n2);//要查询的最近公共祖先的节点对数 while(n2--){ int a,b; scanf("%1s%d%1s%d%1s",s1,&a,s2,&b,s3);//注意输入!!! a--;b--; int depa=depth(a); int depb=depth(b); while(a!=b){ if(depa>depb)a=f[a],depa--; else b=f[b],depb--; } sum[a]++; } for(i=0;i<tempn;i++){ if(sum[i]>0) printf("%d:%d ",i+1,sum[i]); } } return 0; }