自己写的代码(后面1个case答案错误):
//
// main.cpp
// PAT_1032. Sharing
//
// Created by wjq on 17/4/15.
// Copyright © 2017年 wjq. All rights reserved.
//
#include <iostream>
#include <string.h>
#include <map>
using namespace std;
struct Node
{
char c;
int next;
}node[100005];
map<char,int> m;
int start1,start2,N;
string a,b;
char result;
bool Getab(int s1,int s2)
{
while(s1!=-1)
{
a+=node[s1].c;
s1=node[s1].next;
}
while(s2!=-1)
{
b+=node[s2].c;
s2=node[s2].next;
}
long aEnd=a.length()-1,bEnd=b.length()-1;
if(a[aEnd]!=b[bEnd])
return false;
else
{
while(a[aEnd]==b[bEnd]&&aEnd>=0&&bEnd>=0)
{
result=a[aEnd];
aEnd--;
bEnd--;
}
return true;
}
}
int main(int argc, const char * argv[])
{
scanf("%d%d%d",&start1,&start2,&N);
for(int i=0;i<N;i++)
{
int address,next;
char c;
scanf("%d",&address);
getchar();
scanf("%c%d",&c,&next);
node[address].c=c;
node[address].next=next;
m[c]=address;
}
if(Getab(start1,start2)==false)
printf("-1\n");
else
printf("%05d\n",m[result]);
}
我的思路是先从起点1和起点2开始遍历链表,分别把两个字符串a,b求出来,然后再求两个字符串的公共后缀的起始字符,
通过事先建立的map<char , int> 直接输出起始字符的地址.(我这样想的前提是每个字符的地址是唯一的)
参考网上后写的代码:
思路:把s1那次遍历的所有节点都标记vis=1,一旦s2遍历的时候遇到vis=1的节点,可以认为这就是公共后缀的起始节点.
这是单链表的特性:从某个相同的节点出发到尾节点,一定会得到一条完全一致的路径.
//
// main.cpp
// PAT_1032. Sharing
//
// Created by wjq on 17/4/15.
// Copyright © 2017年 wjq. All rights reserved.
//
#include <iostream>
#include <string.h>
#include <map>
using namespace std;
map<int,int> m;
int vis[100005]={0};
int start1,start2,N,result=-1;
int main(int argc, const char * argv[])
{
scanf("%d%d%d",&start1,&start2,&N);
for(int i=0;i<N;i++)
{
int address,next;
char c;
scanf("%d",&address);
getchar();
scanf("%c%d",&c,&next);
m[address]=next;
}
while(start1!=-1)
{
vis[start1]=1;
start1=m[start1];
}
while(start2!=-1)
{
if(vis[start2]==1)
{
result=start2;
break;
}
start2=m[start2];
}
if(result==-1)
printf("-1\n");
else
printf("%05d\n",result);
}