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

相關文章
相關標籤/搜索