我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED
原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805460652113920
题目描述:
题目翻译:
1032 共享
要存储英文单词,一种方法是使用链接列表并逐字逐句地存储单词。为了节省一些空间,如果它们共享相同的后缀,我们可以让这些单词共享相同的子列表。 例如,loading和being按下图所示形式存储。
你需要找出公共后缀的起始位置(图1中是i)。
输入格式:
每个输入文件包含一个测试用例。 对于每个测试用例,第一行包含两个节点地址和一个正整数N(<= 10 ^ 5),其中两个节点地址分别是两个单词的首字母的地址,N是节点的总数。 节点的地址是5位正整数,NULL由-1表示。
然后是N行,每行按以下格式描述一个节点:
Address Data Next
其中Address是节点的位置,Data是该节点包含的字母,它是从{a-z,A-Z}中选择的英文字母,Next是下一个节点的位置。
输出格式:
对于每种情况,只需输出公共后缀的5位起始位置地址即可。如果这两个单词没有共同的后缀,则输出-1代替。
输入样例1:
11111 22222 9
67890 i 00002
00010 a 12345
00003 g -1
12345 D 67890
00002 n 00003
22222 B 23456
11111 L 00001
23456 e 67890
00001 o 00010
输出样例1:
67890
输入样例2:
00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1
输出样例2:
-1
知识点:链表
思路:以静态链表形式存储数据
首先遍历第一个单词的所有节点,标记已遍历到的节点。
其次遍历第二个单词的所有节点,寻找第一个已被标记的节点位置,即公共后缀的起始点位置。
注意输出的时候需要格式化输出,不足5位的地址前面需补0输出。
时间复杂度是O(N)。空间复杂度是O(100000)。
C++代码:
#include<iostream>
using namespace std;
struct node {
char data;
int next;
node() {};
node(char _data, int _next) : data(_data), next(_next) {};
};
node Node[100000];
bool flag[100000];
int main() {
int first1, first2, N, now, next, cur1, cur2;
char c;
scanf("%d %d %d", &first1, &first2, &N);
for(int i = 0; i < N; i++) {
scanf("%d %c %d", &now, &c, &next);
Node[now] = node(c, next);
}
fill(flag, flag + 100000, false);
cur1 = first1;
while(cur1 != -1) {
flag[cur1] = true;
cur1 = Node[cur1].next;
}
cur2 = first2;
while(cur2 != -1) {
if(flag[cur2]) {
break;
}
cur2 = Node[cur2].next;
}
if(cur2 == -1) {
printf("-1\n");
} else {
printf("%05d\n", cur2);
}
return 0;
}
C++解题报告: