PAT A1032 Sharing
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:
存储方式:静态链表
Two point,一个先走,走到后缀等长,另一个也开始同步遍历链表 -
code1:
#include <cstdio>
#include <cstring>
const int maxn = 100010;
struct Node{
char data;
int next;
}node[maxn];
int size(int start){
int count = 0;
int p = start;
//若令p = node[start].next则会出错
while(p != -1){
p = node[p].next;
count++;
}
return count;
}
int findSub(int s1, int s2){
int size1 = size(s1), size2 = size(s2);
if(size1 < size2){
for(int i = 0; i < size2-size1; ++i)
s2 = node[s2].next;
}
if(size1 > size2){
for(int i = 0; i < size1-size2; ++i)
s1 = node[s1].next;
}
while(s1 != -1 && s2 != -1){
if(s1 == s2){
return s1;
}
s1 = node[s1].next;
s2 = node[s2].next;
}
return -1;
}
int main(){
int s1, s2, n;
scanf("%d %d %d", &s1, &s2, &n);
for(int i = 0; i < n; ++i){
int pos, next;
char data;
scanf("%d %c %d", &pos, &data, &next);
node[pos].data = data;
node[pos].next = next;
}
if(findSub(s1, s2) != -1){
printf("%05d", findSub(s1, s2));
}
else{
printf("-1");
}
return 0;
}
- 思路2:
存储方式:静态链表
标记法:使每个node带一个标记位,标记是否被遍历过,先遍历并标记第一个字符串,再遍历第二个,并查看标记位
#include <cstdio>
#include <cstring>
const int maxn = 100010;
struct Node{
char data;
int next;
bool flag;
}node[maxn];
int main(){
//如果在结构体中直接flag=false会报[Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
//在工具 -> 编译选项 -> 编译时加入:添上 -std=c++11 就没有warning了
for(int i = 0; i < maxn; ++i){
node[i].flag = false;
}
int s1, s2, n;
scanf("%d%d%d", &s1, &s2, &n);
int pos, next;
char data;
for(int i = 0; i < n; ++i){
//输入数据
scanf("%d %c %d", &pos, &data, &next);
node[pos].data = data;
node[pos].next = next;
}
while(s1 != -1){
//遍历word1,将每个字符出现的位置标记为true
node[s1].flag = true;
s1 = node[s1].next;
}
while(s2 != -1){
//遍历word2,若出现flag = true 说明和word有重叠,返回相应pos
if(node[s2].flag){
break;
}
s2 = node[s2].next;
}
if(s2 != -1){
//while提前退出,发现子串
printf("%05d", s2);
}
else{
printf("-1");
}
return 0;
}
- T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
unordered_map<int, bool> has;
int nex[maxn];
int main(){
int list1, list2, n;
scanf("%d %d %d", &list1, &list2, &n);
for(int i = 0; i < n; ++i){
int tmp_add, tmp_next;
char tmp_data;
scanf("%d %c %d", &tmp_add, &tmp_data, &tmp_next);
nex[tmp_add] = tmp_next;
}
while(list1 != -1){
has[list1] = true;
list1 = nex[list1];
}
while(list2 != -1){
if(has[list2] == false) has[maxn] = true;
else{
printf("%05d", list2); //Wrong 1: 样例4
break;
}
list2 = nex[list2];
}
if(list2 == -1) printf("-1");
return 0;
}
- T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct Node
{
int nex;
char data;
bool flg;
}node[maxn];
int main()
{
int head1, head2, n;
scanf("%d %d %d", &head1, &head2, &n);
for(int i = 0; i < n; ++i)
{
int add;
scanf("%d", &add);
scanf(" %c %d", &node[add].data, &node[add].nex);
}
while(head1 != -1)
{
node[head1].flg = true;
head1 = node[head1].nex;
}
while(head2 != -1)
{
if(node[head2].flg)
{
printf("%05d", head2);
return 0;
}
head2 = node[head2].nex;
}
printf("-1");
return 0;
}