題意:c++
輸入q,而後輸入q個a,對於每一個a,找到一個b,使gcd(a ^ b, a & b)最大,輸出這個最大的gcd;less
思路:spa
用k表示a二進制最高位的二進制編號,1,2,4,8對應1,2,3,4; code
假如a不是 (1 << k) - 1這種形式的,那麼總能找到一個b使a ^ b == (1 << k) - 1,而a & b == 0,這個時候gcd必定最大。若是a是 (1 << k) - 1,那麼由於b不能爲0,因此湊不出 (1 << k) - 1,沒辦法只能暴力了,由於(1 << k) - 1這樣的形式的a也只有24個,因此咱們要事先打表,不然應該會超時blog
打表代碼:get
#include "bits/stdc++.h" using namespace std; int main() { for (int i = 3; i <= (1 << 25) - 1; i = i << 1 | 1) { int max_gcd = 0; for (int j = 1; j < i; j++) { max_gcd = max(max_gcd, __gcd(i ^ j, i & j)); } printf("mp[%d] = %d;\n", i, max_gcd); } return 0; }
提交代碼:it
C - Meaningless Operations | GNU C++11 | Accepted | 30 ms | 0 KB |
#include "bits/stdc++.h" using namespace std; map<int, int> mp; int main() { mp[3] = 1; mp[7] = 1; mp[15] = 5; mp[31] = 1; mp[63] = 21; mp[127] = 1; mp[255] = 85; mp[511] = 73; mp[1023] = 341; mp[2047] = 89; mp[4095] = 1365; mp[8191] = 1; mp[16383] = 5461; mp[32767] = 4681; mp[65535] = 21845; mp[131071] = 1; mp[262143] = 87381; mp[524287] = 1; mp[1048575] = 349525; mp[2097151] = 299593; mp[4194303] = 1398101; mp[8388607] = 178481; mp[16777215] = 5592405; mp[33554431] = 1082401; int t, n; scanf("%d", &t); while (t--) { scanf("%d", &n); if (mp.count(n)) { printf("%d\n", mp[n]); continue; } int k = 0; while (n) { k++; n >>= 1; } printf("%d\n", (1 << k) - 1); } return 0; }
此次比賽獲得的教訓是打表程序跑出來的結果必定要是能夠直接複製粘貼的,比賽的時候前面的題原本就作的不夠快,而後當時打表程序不夠好,這題還手敲了switch,結果來不及提交了。仍是map好,沒有引號百分號,用printf輸出比較方便。io