题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1032
模拟单词存储
原生态版
// NULL定义在stdio.h中,为0, 所以本题中直接用-1,不要用NULL
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#define SIZE 100000+10
#define NULL -1 //会提示重复定义
using namespace std;
struct Node
{
int addr;
char data;
int next;
bool operator < (const Node& A) const
{
return addr < A.addr;
}
};
Node buf[SIZE];
int addr1, addr2, N;
int len1=0, len2=0;
void Init()
{
memset(buf, 0, sizeof(buf));
len1 = len2 = 0;
}
void Input()
{
scanf("%d%d%d", &addr1, &addr2, &N);
int i;
for(i=0; i<N; i++)
{
scanf("%d %c %d", &buf[i].addr, &buf[i].data, &buf[i].next);
}
}
int search(int addr)
{
int low=0, high=N-1;
while(low <= high)
{
int mid = (low+high)/2;
if(buf[mid].addr == addr)
{
return mid;
}
else if(buf[mid].addr < addr)
{
low = mid+1;
}
else
{
high = mid-1;
}
}
return low;
}
void GetLen(int addr, int &len)
{
int p=addr;
while(p != NULL)
{
len++;
p = buf[search(p)].next;//move to next
}
}
void Find()
{
GetLen(addr1, len1);
GetLen(addr2, len2);
// printf("len1:%d\n", len1);
// printf("len2:%d\n", len2);
if(len1 > len2)
{
int dis=len1-len2;
while(dis-->0)
{
addr1 = buf[search(addr1)].next;
}
}
if(len2 > len1)
{
int dis=len2-len1;
while(dis-->0)
{
addr2 = buf[search(addr2)].next;
}
}
//一起后移
while(addr1 != addr2)//二者如果都移动到NULL,则相同
{
addr1 = buf[search(addr1)].next;
addr2 = buf[search(addr2)].next;
}
if(addr1 != -1)
{
printf("%05d\n", addr1);
}
else
{
printf("-1\n");
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif
Init();
Input();
sort(buf, buf+N);
Find();
return 0;
}
改进版
// -----------------------------------------------
// 但是吧,单词又没用到,还是可以简化一下,使用hash,减去查找到麻烦
#include <stdio.h>
#include <string.h>
#define SIZE 100000+10
int word[SIZE];
int start1, start2;
int n;
void Init()
{
memset(word, -1, sizeof(word));
}
int GetLen(int start)
{
int len=0;
while(start != -1)
{
start=word[start];
len++;
}
return len;
}
int abs(int x)
{
return x>=0 ? x:-x;
}//
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif
scanf("%d%d%d", &start1, &start2, &n);
while(n-->0)
{
int x, y;//x->y
char s[2];
scanf("%d %s %d", &x, s, &y);
word[x] = y;
}
int len1=GetLen(start1);
int len2=GetLen(start2);
if(len1 > len2)
{
int dis=len1-len2;
while(dis-->0)
{
start1=word[start1];
}
}
if(len2 > len1)
{
int dis=len2-len1;
while(dis-->0)
{
start2=word[start2];
}
}
while(start1 != start2)
{
start1=word[start1];
start2=word[start2];
}
if(start1 == -1)
{
printf("-1\n");
}
else
{
printf("%05d\n", start1);
}
return 0;
}
大神版
// 大神的思想
#include <cstdio>
#include <cstring>
using namespace std;
int node[100000],temp[100000];
int main()
{
memset(node,-1,sizeof(node));
int start1,start2,n,from,to;
char s[2];
scanf("%d %d %d",&start1,&start2,&n);
for( int i=0; i<n; i++)
{
scanf("%d %s %d",&from,s,&to);
node[from] = to;
}
while(start1 != -1)
{
temp[start1] = 1;
start1 = node[start1];
}// 暂存单词1的轨迹
while(start2 != -1)
{
if(temp[start2])
{
printf("%.5d\n",start2);
return 0;
}// 单词2与1有相同轨迹时
start2 = node[start2];
}
printf("-1\n");
return 0;
}