PTA甲级—链表

1032 Sharing (25分)node

回顾了下链表的基本使用,这题就是判断两个链表是否有交叉点。ios

我最开始的作法就是用cnt[]记录每一个节点的入度,发现入度为2的节点即为答案。后来发现这里忽略了两个链表初始节点都是同样的状况,因而这里cnt[]的含义变为每一个节点被引用的次数,当一个节点被引用两次就说明被两个链表同时引用。此时又经过了部分测试样例,但是测试样例5始终经过不了。后来偶然翻到一篇博客才恍然大悟,这里的节点可能不止包含两个单词,便可能有多个起点表示多个单词,而题目只是问你给定的两个单词有没有相同后缀,那以前的思路就不适用了。ide

正确的作法应当是先遍历第一个单词,给全部节点的引用次数+1;接着遍历第二个单词,一样给路径上的节点引用次数+1,发现有两次引用的节点即为答案。最后记得要控制输出的格式,这点在不少题目中都考察过测试

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <set>
#define ll long long
#define inf 0x3f3f3f
#define pii pair<int, int>
#define pb push_back
using namespace std;
const int maxn = 1e5+100;
struct node{
    char data;
    int nxt = -1;
}link[maxn]; 
int pa, pb, m, now, val, nextNode;
int cnt[maxn], res = -1;
int main(){
    scanf("%d%d%d", &pa, &pb, &m);
    while(m--){
        scanf("%d %c %d", &now, &val, &nextNode);
        link[now].data = val, link[now].nxt = nextNode;
    }
    while(pa!=-1) cnt[pa]++, pa = link[pa].nxt;
    while(pb!=-1){
        if(++cnt[pb]==2){
            res = pb;
            break;
        }
        pb = link[pb].nxt;
    }
    if(res==-1) printf("-1");
    else printf("%05d", res);
}
View Code

Reference:spa

https://www.amoshuang.com/archives/774.net

https://blog.csdn.net/qq_39072627/article/details/1070081043d

 

1052 Linked List Sorting (25分)调试

题意对链表进行排序并输出。有了1032这题的经验,WA后很快就发现输入的数据不必定在都在链表中。修改过来后缝缝补补,很快就AC了,不过须要注意一些细节,否则也可能过不了code

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <set>
#define ll long long
#define inf 0x3f3f3f
#define pii pair<int, int>
#define pb push_back
using namespace std;
const int maxn = 1e5+100;
pii g[maxn];
int n, pos, now, val, nextNode;
struct node{
    int val, nxt;
}link[maxn];
int main(){
    scanf("%d%d", &n, &pos);
    for(int i = 1; i <= n; i++){
        scanf("%d%d%d", &now, &val, &nextNode);
        link[now] = {val, nextNode};
    }
    int t = 0;
    while(pos!=-1) g[++t] = {link[pos].val, pos}, pos =link[pos].nxt;
    sort(g+1, g+1+t);
    printf("%d ", t);
    if(t==0) printf("-1\n");
    else{
        printf("%05d\n", g[1].second);
        for(int i = 1; i <= t; i++){
            printf("%05d %d ", g[i].second, g[i].first);
            if(i!=t) printf("%05d\n", g[i+1].second);
            else printf("-1\n");
        }    
    }
    
}
View Code

Reference:blog

https://blog.csdn.net/qq_39072627/article/details/107009532

https://blog.csdn.net/LSC_333/article/details/91356270

 

1074 Reversing Linked List (25分)

按照给定的k值,链表每k个节点为一组翻转一次,个人思想是对的,可是实现的方法有点啰嗦不直观,致使WA后调试起来也很麻烦。后面参考别人的作法,记录整个链表翻转后的下标,直接输出便可

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <set>
#define ll long long
#define inf 0x3f3f3f
#define pii pair<int, int>
#define pb push_back
using namespace std;
const int maxn = 1e5+100;
pii g[maxn];
int n, pos, k, now, val, nextNode;
int res[maxn];
struct node{
    int val, nxt;
}link[maxn];
int main(){
    scanf("%d%d%d", &pos, &n, &k);
    for(int i = 1; i <= n; i++){
        scanf("%d%d%d", &now, &val, &nextNode);
        link[now] = {val, nextNode};
    }
    int t = 0;
    while(pos!=-1) g[t++] = {link[pos].val, pos}, pos =link[pos].nxt;
    for(int i = 0; i <= t-1; i++) {
        if(i<t-t%k) res[i] = (i/k)*k*2+k-1-i;
        else res[i] = i;
    }
    for(int i = 0; i <= t-1; i++){
        printf("%05d %d ", g[res[i]].second, g[res[i]].first);
        if(i!=t-1) printf("%05d\n", g[res[i+1]].second);
        else printf("-1\n");
    }    
}
View Code

Reference:

https://blog.csdn.net/qq_41325698/article/details/103466109

相关文章
相关标签/搜索