题解:
根据题意,最简单的思路就是把这n个数全部两两加起来,然后依次判断和是否是2的幂次方,只不过时间复杂度过高,在题目所给的n范围内无法通过;
再思考思考, ,
移项可得:
所以我们可以这样只需要枚举 ;
然后用 在剩余的a[i + 1] ~ a[n - 1]个数中查找存在多少个
就可以解决问题了。
由于给定的ai <= 1e9, 即ai + aj< 2^31,所以x枚举的时候只需要枚举0到30就足够了。
查找的时候可以利用二分查找来优化查找时间。
使用low来记录第一个大于等于key的位置、使用up来记录第一个大于key的位置,那么两个位置的差就是数列中key的个数。
注意,结果会爆int,需要long long记录。
时间复杂度
空间复杂度
/**
* 返回n个数中一共有多少对数之和为2的幂次方
* @param n int整型 代表一共有多少数
* @param a int整型vector 代表每个数字的大小
* @return long长整型
*/
long long solve(int n, vector<int> &a)
{
// write code here
int atw[33] = {0};
for (int i = 0; i <= 30; i++)
atw[i] = 1 << i;
sort(a.begin(), a.end());
long long ans = 0;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j <= 30; j++)
{
int key = atw[j] - a[i];
int low = lower_bound(a.begin() + i + 1, a.end(), key) - a.begin();
int cnt = 0;
if (a[low] == key)
{
int up = upper_bound(a.begin() + i + 1, a.end(), key) - a.begin();
cnt = up - low;
}
ans += cnt;
}
}
return ans;
}
京公网安备 11010502036488号