分析程式**
最大異或對,就是給出一堆數,然後在這一堆數中選擇兩個數,使得異或後結果最大。所涉及到的知識點有:字典樹,二進位制的思想
);這樣寫不出意外是會超時的,因為這樣看的話,他的時間複雜度是
o(n * n)
,然後題中給出的資料是10的五次方
。所以說這樣的話,需要執行
10的十次方
次操作,而機器在一秒中只能執行10的七次方 -- 10的八次方
次操作,這樣來看肯定超時。題目給的資料是31位的,二級制每乙個數都是獨一無二的,我們可以用乙個32層的樹(根節點沒有資料)來表示二級制的每乙個結點,那麼每乙個到葉子節點的路徑就可以組成乙個二進位制數。
這裡需要注意,我們建樹的過程需要從乙個數的高位開始,逐漸向低位拓展。而不能先判斷地位。
** 注意的點**//插入資料到字典樹中,乙個根的左節點是1,右節點是0
void
insert
(int num)
}
理解異或
如何實現
這樣我們就可以把原本的//找到與這個數異或後最大的結果
intfind
(int num)
else
p = son[p]
[s];
}return ret;
}
10的十次方
的時間複雜度降低到10的五次方 * 31
,幾乎是o(n)
了。const
int n =
100010
;const
int m = n *31;
int num[n]
;//儲存每乙個數的陣列
//son[i][0] 表示第i個節點的左孩子的id son[i][1]表示第i個點右孩子的id
int son[m][2
];//模擬乙個字典樹,
int id;
//給每乙個結點編號
#include
#include
using
namespace std;
const
int n =
100010
;const
int m = n *31;
int num[n]
;//儲存每乙個數的陣列
//son[i][0] 表示第i個節點的左孩子的id son[i][1]表示第i個點右孩子的id
int son[m][2
];//模擬乙個字典樹,
int id;
//給每乙個結點編號
//插入資料到字典樹中,乙個根的左節點是1,右節點是0
void
insert
(int num)
}//找到與這個數異或後最大的結果
intfind
(int num)
else
p = son[p]
[s];
}return ret;
}int
main()
int ans =0;
//找異或的最大值
for(
int i =
0; i < n; i++
) ans =
max(ans,
find
(num[i]))
;
cout<
return0;
}
最大異或對 字典樹
在給定的n個整數a1,a2 an中選出兩個進行xor 異或 運算,得到的結果最大是多少?輸入格式 第一行輸入乙個整數n。第二行輸入n個整數a1 an。輸出格式 輸出乙個整數表示答案。資料範圍 1 n 105,0 ai 231 輸入樣例 31 2 3 輸出樣例 3 基於貪心的思想 異或是一種不進製加法...
最大異或對 字典樹)
143.最大異或對 在給定的n個整數a1,a2 an a1,a2 an 中選出兩個進行xor 異或 運算,得到的結果最大是多少?輸入格式 第一行輸入乙個整數n。第二行輸入n個整數a 1 a1 an an 輸出格式 輸出乙個整數表示答案。資料範圍1 n 105 1 n 10 5,0 ai 231 0 ...
字典樹 最大異或對
給你 n 個數,從中選兩個數進行異或運算,得到結果最大是多少 一道沒寫過就不知道怎麼寫的套路題 剛開始可以用貪心分析,也就是說如果兩個數的高位能夠盡可能的大那麼我們就盡可能的大就好了,也就是說兩個數的二進位制數在同一位不同,此時最大,那麼怎樣很快的滿足呢?我們發現可以將二進位制數轉化到trie上面解...