前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【PAT甲级】Sharing

【PAT甲级】Sharing

作者头像
喜欢ctrl的cxk
发布2019-11-08 14:51:05
3650
发布2019-11-08 14:51:05
举报
文章被收录于专栏:Don的成长史Don的成长史

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42449444/article/details/89674601

Problem Description:

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.

fig.jpg
fig.jpg

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 (≤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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
67890

Sample Input 2:

代码语言:javascript
复制
00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1

Sample Output 2:

代码语言:javascript
复制
-1

解题思路:

我一开始的思路是:先用一个map来记录每个字符所对应的结点地址(map的key是字符,map的value是结点所在地址),然后按照顺序把结点存放在2个vector里,还原出俩个单词word1、word2(类型为string)。接下来就是找共同后缀啦,用ans(初始化为-1)来记录这俩个单词的共同后缀的起始结点地址,最后从后往前找出这俩个单词的共同后缀的起始结点地址进行输出即可。然而!提交代码之后有2个测试点出现了WA,这就很难受啦。果断换了一种思路,让你WA!老子生气啦!?我不还原出那2个单词啦,直接用set来记录出现第一个单词中出现过的字符所在结点地址,用flag来判断俩个单词是否有共同后缀,要是第二个单词中某个字符所在结点地址也出现在了set中果断用ans来记录这个结点地址并标记flag为true,否则flag为false输出-1。

AC代码: 20分代码:

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
#define MAX 100005

struct Node
{
    int address;   //当前结点的地址
    char data;     //当前结点的数据
    int next;      //下一结点的地址
}node[MAX];

int main()
{
    int Head1,Head2,N;
    cin >> Head1 >> Head2 >> N;
    map<char, int> m;  //map用来记录每个字符所对应的结点地址
    for(int i = 0; i < N; i++)
    {
        int temp;
        cin >> temp;
        node[temp].address = temp;
        cin >> node[temp].data >> node[temp].next;
        m[node[temp].data] = temp;
    }
    vector<Node> v1,v2;  //按照顺序来存放结点
    string word1 = "", word2 = "";   //第一个单词word1,第二个单词word2
    for(int i = Head1; i != -1; i = node[i].next)
    {
        v1.push_back(node[i]);
        word1 += node[i].data;
    }
    for (int i = Head2; i != -1; i = node[i].next)
    {
        v2.push_back(node[i]);
        word2 += node[i].data;
    }
    // cout << word1 << " " << word2 << endl;
    bool flag = false;   //判断word1、word2有没有共同后缀
    int ans = -1;   //用来记录word1、word2共同后缀的起始结点地址
    for(int i = word1.length()-1, j = word2.length()-1; word1[i] == word2[j]; i--, j--)
    {
        flag = true;
        ans = m[word1[i]];
    }
    if(flag)   //若word1、word2有共同后缀
    {
        printf("%05d\n", ans);
    }
    else   //若没有共同后缀,输出-1。-1是不需要前置补0的
    {
        cout << ans << endl;
    }
    return 0;
}

AC代码:

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
#define MAX 100005

struct Node
{
    int address;   //当前结点的地址
    char data;     //当前结点的数据
    int next;      //下一结点的地址
}node[MAX];

int main()
{
    int Head1,Head2,N;
    cin >> Head1 >> Head2 >> N;
    for(int i = 0; i < N; i++)
    {
        int temp;
        cin >> temp;
        node[temp].address = temp;
        cin >> node[temp].data >> node[temp].next;
    }
    bool flag = false;   //判断word1、word2有没有共同后缀
    int ans = -1;   //用来记录word1、word2共同后缀的起始结点地址
    set<int> s;   //用来记录word1中出现过的字母所在结点地址
    vector<Node> v;  //按照顺序来存放word1中的结点
    for(int i = Head1; i != -1; i = node[i].next)
    {
        v.push_back(node[i]);
        s.insert(node[i].address);
    }
    for (int i = Head2; i != -1; i = node[i].next)
    {
        if(s.count(node[i].address) != 0)
        {
            flag = true;   //说明word1、word2存在共同后缀
            ans = node[i].address;
            break;
        }
    }
    if(flag)   //若word1、word2有共同后缀
    {
        printf("%05d\n", ans);
    }
    else   //若没有共同后缀,输出-1。-1是不需要前置补0的
    {
        cout << ans << endl;
    }
    return 0;
}

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Problem Description:
  • Input Specification:
  • Output Specification:
  • Sample Input 1:
  • Sample Output 1:
  • Sample Input 2:
  • Sample Output 2:
  • 解题思路:
  • AC代码: 20分代码:
  • AC代码:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档