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.
Figure 1
You are supposed to find the starting position of the common suffix (e.g. the position of i
in Figure 1).
Input Specification:
Each input file contains one test case. For each case, the first line contains two addresses of nodes and a positive N (≤105), 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
whereAddress
is the position of the node, Data
is the letter contained by this node which is an English letter chosen from { a-z, A-Z }, and Next
is the position of the next node.
Output Specification:
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.
Sample Input 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
Sample Output 1:
67890
Sample Input 2:
00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1
Sample Output 2:
-1
要存储英语单词,一种方法是使用链表并逐个字母存储单词。
为了节省一些空间,如果单词共享相同的后缀,我们可能会让它们共享相同的子列表。
例如,加载和存在如图 1 所示进行存储。 您应该找到公共后缀的起始位置(例如图 1 中 i 的位置)。
输入规范:每个输入文件包含一个测试用例。对于每种情况,第一行包含两个节点地址和一个正 N (≤10 5 ),其中这两个地址是两个单词的第一个节点的地址,N 是节点总数。节点的地址是 5 位正整数,NULL 用 −1 表示。 然后是 N 行,每行描述一个节点的格式为:地址数据下一个,其中地址是节点的位置,数据是这个节点包含的字母,它是从 { a-z, A-Z } 中选择的英文字母,下一个是下一个节点的位置。
输出规格:对于每种情况,只需输出公共后缀的 5 位起始位置。(简单来说就是后缀开始的那个字母的位置)如果这两个单词没有共同的后缀,则改为输出 -1。
//解析:
//找到后缀开始非常容易,即我们只需要先将第一个单词的所有数据标记确认,
// 然后查找第二个单词,一旦在链表中找到相同的字母就表示后缀的开始,然后存储该点位置即可
//
//标记的优势:只要在第二个单词中找到了第一个单词的位置下标,
// 就表示两个单词的这个字母重合,就可以直接得出答案
//这样就避免使用相同字母判断第一个后缀的方法。
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#include<iomanip>//调用setfill和setw
using namespace std;
class node
{
public:
//别忘了声明公共!
char data;//类型不要惯性写int!
//int pos;当前的位置已经有容器的下标表示了!
int nextpos = -1;//题目设置为-1表示NULL,我们这里初始化为-1,先设置好链尾。
//一旦没有了数据,那么初始化为-1就表示为链尾.
int visited = 0;
};
int main()
{
vector<node> list(100010);
int beginpos1, beginpos2, n;
cin >> beginpos1 >> beginpos2 >> n;
for (int i = 0; i < n; i++)
{
int inpos, inNextpos;
char indata;
cin >> inpos >> indata >> inNextpos;
list[inpos].data = indata;//这个其实不写也行,题目不需要这个数据也可以求出后缀位置
list[inpos].nextpos = inNextpos;
}
int t = beginpos1;
while (true)//遍历第一个单词并标记
{
/*if (list[t].nextpos == -1)
break;*///err,不是下一个节点为空
//为了全部都要遍历到是当前为空的时候我才退出
if (t == -1)
break;
else
{
//list[t].visited == 1;
list[t].visited = 1;//多写了个=,我吐了。
//找半天bug
t = list[t].nextpos;
}
}
int judge = 0, tmp = beginpos2, pos;
while (true)
{
//if (list[tmp].nextpos == -1)
// break; err
if (tmp == -1)
break;
if (list[tmp].visited == 1)//表示找到相同单词,即后缀开始
{
judge = 1;
pos = tmp;
break;
}
else
tmp = list[tmp].nextpos;
}
if (judge == 1)
{
cout << setfill('0') << setw(5) << pos << endl;
//setfill() 是用来填充数字的控制符,setw() 是用来设置输出宽度的控制符。
//这里使用 setfill('0') 可以使输出结果中的数字左对齐。
//setfill不加字符默认为空格字符
//两个叠在一起使用的时候就是,pos输出,当pos不满5格时,左边补0补满5格
}
else
{
cout << -1 << endl;
}
return 0;
}