#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
pair<int,int> a[10005];
int cun[10005];
int cun1[10005];
bool cmp(pair<int,int> a,pair<int,int> b)
{
return a.second<b.second;
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
int n,b,c;
memset(a,0,sizeof(a));
memset(cun,0,sizeof(cun));
memset(cun1,0,sizeof(cun1));
scanf("%d",&n);
for(int i=1; i<=n-1; i++)
{
scanf("%d%d",&a[i].first,&a[i].second);
}
scanf("%d%d",&b,&c);
//printf("sort ready do\n");
sort(a,a+n,cmp);
//printf("sort is done\n");
int num;
for(int i=1; i<=n-1; i++)
if(i!=a[i].second)
{
num=i;
break;
}
int k1=1,k2=1;
cun[0]=b;
cun1[0]=c;
while(b!=num)
{
int left=1,right=n-1;
int mid;
while(left<=right)
{
mid=(left+right)/2;
if(b==a[mid].second)
{
cun[k1++]=a[mid].first;
b=a[mid].first;
break;
}
else if(b<a[mid].second) right=mid-1;
else if(b>a[mid].second) left=mid+1;
}
}
//printf("1binsearch is done\n");
while(c!=num)
{
int left=1,right=n-1;
int mid;
while(left<=right)
{
mid=(left+right)/2;//printf("mid:%d\n",mid);
if(c==a[mid].second)
{
cun1[k2++]=a[mid].first;
c=a[mid].first;
break;
}
else if(c<a[mid].second) right=mid-1;
else if(c>a[mid].second) left=mid+1;
}
//printf("c:%d\n",c);
}
//printf("2binsearch is done\n");
int flag=0;
for(int i=0; i<k1; i++)
{
for(int j=0; j<k2; j++)
{
if(cun[i]==cun1[j])
{
printf("%d\n",cun[i]);
flag=1;
break;
}
}
if(flag) break;
}
}
return 0;
}
重要教训:
for(int i=1; i<=n-1; i++)
{
scanf("%d%d",&a[i].first,&a[i].second);
}
scanf("%d%d",&b,&c);
//printf("sort ready do\n");
sort(a,a+n,cmp);
因为for(int i=1;i<=n-1;i++)中的i<=n-1的缘故,错误的代码把sort写成了sort(a,a+n-1,cmp);导致最后一组数据没有被排序,最终使后面的二分查找是在一个没有完全排序的数组中进行查找,导致有些数据会变成死循环。
所以以后的好习惯就是在for(;;)的判断条件中,不要出现"<=",应该一行字用'<'代替它
for(int i=1; i<n; i++)
{
scanf("%d%d",&a[i].first,&a[i].second);
}
scanf("%d%d",&b,&c);
//printf("sort ready do\n");
sort(a,a+n,cmp);
通过这道题也学会了许多调试技巧,例如一开始OJ判断超时的时候我以为是sort()太慢了,用
printf("sort ready do\n");
sort(a,a+n,cmp);
printf("sort is done\n");
加以判断。
通过在代码运行过程中添加输出信息可以明白代码运行到哪儿了,是一个很好的调试技巧。