1032 Sharing (25分)
题目描述
To store English words, one method is to use linked lists and store a word letter by letter. To save some space, we may let the words share the same sublist if they share the same suffix. For example, loading and being are stored as showed in Figure 1.
You are supposed to find the starting position of the common suffix (e.g. the position of i in Figure 1).
输入格式
Each input file contains one test case. For each case, the first line contains two addresses of nodes and a positive N (≤10?510?^{5}10?5?? ), where the two addresses are the addresses of the first nodes of the two words, and N is the total number of nodes. The address of a node is a 5-digit positive integer, and NULL is represented by ?1.
Then N lines follow, each describes a node in the format:
Address
Data Next
For each case, simply output the 5-digit starting position of the common suffix. If the two words have no common suffix, output -1
instead.
输出格式
For each test case, simply print the dominant color in a line.
Sample Input1:
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
Sample Output1:
67890
Sample Input2:
00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1
Sample Output2:
-1
总结
-
这题又是某年408的题- -。首先先说存储结构吧,这题静态链表存储比较简单,直接开个数组就可以。
-
我用了两种方法求解这个题,法一是双指针法,法二是设置标志位法。双指针法在链表的问题很常见,链表的判断是否有环也可以用。思路如下:
- step1:先计算出两个链表的长度len1,len2,然后让长度较长的链表移动abs(len1-len2)个位置。
- step2:同时移动两根指针,直到两个指针的地址相等时或指针为空时跳出。
- step3:判断指针地址是否为-1,是则没有公共后缀,否则输出指针地址。
-
法二更简单,直接在结构体里多了个标志位flag,把链表1的标志位全部设置为true,遍历链表2,遇到首个为true则跳出。接下来判断当前地址是否为空就行。
-
注意!!地址输出要5位输出,不够补0。PAT这个套路你发现了没?
AC代码
解法1
#include <iostream>
using namespace std;
struct node {
int next;char data;
}linkNode[100000];
int getLength(int address) {
//递归求链表长度(为了练习递归)return address == -1 ? 0 : getLength(linkNode[address].next) + 1;
}
int main( )
{
int p1, p2, n, cur, next, step;char letter;scanf("%d%d%d", &p1, &p2, &n);while (n--) {
scanf("%d %c %d", &cur, &letter, &next);linkNode[cur].data = letter;linkNode[cur].next = next;}int len1 = getLength(p1);int len2 = getLength(p2);step = len1 - len2 > 0 ? len1 - len2 : len2 - len1;if (len1 > len2) {
while (step--) {
p1 = linkNode[p1].next;}}else while (step--) p2 = linkNode[p2].next;while (p1 != p2 && p1 != -1 && p2 != -1) {
p1 = linkNode[p1].next;p2 = linkNode[p2].next;}if (p1 == -1 || p2 == -1) printf("-1\n");else printf("%05d\n",p1);return 0;
}
解法2
#include <iostream>
using namespace std;
struct node {
int next;char data;bool flag;
}linkNode[100000];
int main()
{
int p1, p2, n, cur, next, target;char letter;scanf("%d%d%d", &p1, &p2, &n);while (n--) {
scanf("%d %c %d", &cur, &letter, &next);linkNode[cur].data = letter;linkNode[cur].next = next;}for (target = p1; target != -1; target = linkNode[target].next) {
linkNode[target].flag = true;}for (target = p2; target != -1; target = linkNode[target].next) {
if (linkNode[target].flag) break;}if (target == -1) printf("-1\n");else printf("%05d\n", target);return 0;
}