【超简洁】1075 链表元素分类 (25分)_34行代码AC
立志用更少的代碼做更高效的表達
Pat乙級最優化代碼+題解+分析匯總——>傳送門
給定一個單鏈表,請編寫程序將鏈表元素進行分類排列,使得所有負值元素都排在非負值元素的前面,而 [0, K] 區間內的元素都排在大于 K 的元素前面。但每一類內部元素的順序是不能改變的。例如:給定鏈表為 18→7→-4→0→5→-6→10→11→-2,K 為 10,則輸出應該為 -4→-6→-2→7→0→5→10→18→11。
輸入格式:
每個輸入包含一個測試用例。每個測試用例第 1 行給出:第 1 個結點的地址;結點總個數,即正整數N (≤10^?5 );以及正整數K (≤10^?3)。結點的地址是 5 位非負整數,NULL 地址用 ?1 表示。
接下來有 N 行,每行格式為:
Address Data Next
其中 Address 是結點地址;Data 是該結點保存的數據,為 [?105,105] 區間內的整數;Next 是下一結點的地址。題目保證給出的鏈表不為空。
輸出格式:
對每個測試用例,按鏈表從頭到尾的順序輸出重排后的結果鏈表,其上每個結點占一行,格式與輸入相同。
輸入樣例:
00100 9 10
23333 10 27777
00000 0 99999
00100 18 12309
68237 -6 23333
33218 -4 00000
48652 -2 -1
99999 5 68237
27777 11 48652
12309 7 33218
輸出樣例:
33218 -4 68237
68237 -6 48652
48652 -2 12309
12309 7 00000
00000 0 99999
99999 5 23333
23333 10 00100
00100 18 27777
27777 11 -1
思路分析
題意:給定一個鏈表, 要求把它分成三部分
1、值小于0的部分
2、值在[0, k]之間的部分
3、值大于k的部分。
保證鏈表的相對順序不變。 如在篩選值小于0的部分時,原鏈表中,-4在第一位,那么在新鏈表中,-4也要在第一位。
思路:
最初的思路:新建一個鏈表,將原有鏈表遍歷三次,每次篩選出對應的部分插入到新鏈表的尾部。
缺點:效率低,麻煩。
和朋友交流后,得到一個全新的牛叉思路:
牛叉思路:
1、構建結構體鏈表
2、遍歷鏈表,按題給要求,找到對應的部分,將其地址用數組存儲。
3、將三個數組合并,遍歷數組,輸出值。
牛叉思路的牛叉之處在于:僅僅針對鏈表的地址進行操作,最后只得到了存儲地址的數組,并不是一個真正的鏈表,它只是“邏輯上”相連,因此效率高,更簡單。
#include<bits/stdc++.h> #define Max 100010 using namespace std;struct LNode{int value;int Next; }l1[Max]; int main() {int fir, n, v; cin >> fir >> n >> v;for(int i = 0; i < n; i++) {int add, x, add_next;cin >> add;cin >> l1[add].value >> l1[add].Next;}vector<int>v1, v2, v3;while(fir != -1) { if(l1[fir].value < 0) {v1.push_back(fir);} else if(l1[fir].value>=0 && l1[fir].value<=v) {v2.push_back(fir);} else if(l1[fir].value > v) v3.push_back(fir);fir = l1[fir].Next; }v1.insert(v1.end(), v2.begin(), v2.end());v1.insert(v1.end(), v3.begin(), v3.end());for(int i = 0; i < v1.size(); i++) {printf("%05d %d ", v1[i], l1[v1[i]].value);if(i < v1.size()-1) printf("%05d\n", v1[i+1]);else printf("-1\n");}return 0; }
耗時
每日一句
要活成兩種樣子,發光和不發光。不發光的時候,都是在為發光做準備~
總結
以上是生活随笔為你收集整理的【超简洁】1075 链表元素分类 (25分)_34行代码AC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【简便解法】1074 宇宙无敌加法器 (
- 下一篇: 【最简代码】1076 Wifi密码 (1