返回列表 發帖

2022 D-亞馬遜寶藏

D-亞馬遜寶藏
時間限制 5 秒 / 記憶體限制 2 G
傳說中亞馬遜的地下存在有大量寶藏,雖然我不是探險家但這聽起來很棒對吧?但要獲取這個寶藏前
要先解出一道謎題,必須要從整數序列中找出最長的子序列,此子序列必須滿足以下條件

1. 序列中任意兩個元素相減的絕對值必須為整數 的任一次方數,也就是 ,例如
,則 。
經過前面探險家的努力,他們已經發現這是個崇拜數字 的民族2ㄏ2ㄏ族所埋下的寶藏,因此這個整
數 一定是正整數 ,
你的任務是找出符合條件的最長子序列並輸出其長度即可。
● 輸入說明
第⼀⾏為一個正整數 ,代表整數序列的長度。
第二行有 個整數 ,代表整數序列中的每個元素,且中間用空白隔開。
, ( )
, ( , )
● 輸出說明
輸出題目要求中最長子序列的長度,若不存在則輸出 。
範例輸入1
6
1 2 5 3 8 10
範例輸出1
3
範例輸入2
5
-1 2 5 11 14
範例輸出2
0
附件: 您需要登錄才可以下載或查看附件。沒有帳號?註冊
May

回復 1# may
  1. #include <bits/stdc++.h>
  2. //#include <iostream>
  3. //#include <vector>
  4. //#include <unordered_map>
  5. //#include <unordered_set>
  6. //#include <algorithm>

  7. using namespace std;

  8. int findLongestSubsequence(vector<int>& arr) {
  9.     unordered_map<int, int> dp;  // dp[x] 表示以 x 結尾的最長子序列長度
  10.     unordered_set<int> numSet(arr.begin(), arr.end());  // 方便快速查找數字是否存在
  11.     int maxLen = 0;

  12.     // 遍歷所有數字,嘗試找出最大合法子序列
  13.     for (int x : arr) {
  14.         dp[x] = 1;  // 最短長度至少為 1(只包含自己)

  15.         for (int p = 0; p <= 29; p++) {
  16.             int diff = 1 << p;  // 2^p
  17.             if (numSet.count(x - diff)) {
  18.                 dp[x] = max(dp[x], dp[x - diff] + 1);
  19.             }
  20.         }

  21.         maxLen = max(maxLen, dp[x]);
  22.     }

  23.     return maxLen > 1 ? maxLen : 0;  // 若 maxLen = 1,代表無法形成合法子序列
  24. }

  25. int main() {
  26.     int n;
  27.     cin >> n;
  28.     vector<int> arr(n);
  29.     for (int i = 0; i < n; i++) {
  30.         cin >> arr[i];
  31.     }

  32.     cout << findLongestSubsequence(arr) << endl;
  33.     return 0;
  34. }
複製代碼
-----------------------------------------------------
用 unordered_map<int, int> 作為 DP 陣列

dp[x] 記錄以 x 為結尾的最大合法子序列長度。

遍歷 arr,對每個 x,檢查 x - 2^p 是否存在。

確保計算正確的子序列長度

只考慮 已出現過的數字,不會多算未來可能的子序列。

時間複雜度為 O(n log n)

O(n) 遍歷數列

O(log n) 嘗試不同的 2^p
--------------------------------------
測資:
測資00:基本測試(來自題目)
解釋:[1, 3, 5] 是符合條件的最長子序列,長度為 3
6
1 2 5 3 8 10
✅ 預期輸出:
3

測資01:無法形成子序列
解釋:沒有兩個數的差是 2^p,所以答案應該是 0
5
-1 2 5 11 14
✅ 預期輸出:
0

測資 02:所有數字皆可形成子序列
解釋:[2, 4, 6, 10] 是符合條件的最長子序列,長度為 4
6
2 4 6 10 16 18
✅ 預期輸出:
4

測資 03:所有數字相同
解釋:所有數字相同,無法形成有效子序列,因此答案為 0
5
7 7 7 7 7
✅ 預期輸出:
0
測資 04:較大數字測試
解釋:[100, 104, 108, 112] 是符合條件的最長子序列,長度為 4
7
100 104 108 112 120 130 140
✅ 預期輸出:
4
這些測資涵蓋:

基本測試

無法形成子序列的情況

可以形成長子序列

所有數字相同的極端情況

較大數字的測試
May

TOP

返回列表