CodeForces - 988D
- 题意
给你n个不同的点的坐标(一维),找出最大的子集,子集满足,任意两点之间的距离为2k,k为非负整数。 - 思路:结果只能有三种1,2,3。即子集最大为3(原因自己思考)。
- 坑点:注意lower_bound搜索的边界,若搜索不到则返回右边界的下一位,所以要特判一下。
#include<bits/stdc++.h>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<string.h>
#include<string>
#include<iostream>
#include<cmath>
#include<map>
#include<algorithm>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define ft first
#define sd second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ll long long int
#define mt(a,b) memset(a, b, sizeof a)
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
using namespace std;
const int N = 2e5, M = 1e6;
int a[N], b[N];
int main()
{
IOS;
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
int ans = 1;
int q = log2(a[n] - a[1]) + 1;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= q; j++)
{
int cnt = 0;
int idx = lower_bound(a + i, a + n + 1, a[i] + (int)pow(2, j)) - a;
if (a[idx] == a[i] + (int)pow(2, j) && idx != n + 1) cnt++;
int idx2 = lower_bound(a + 1, a + i, a[i] - (int)pow(2, j)) - a;
if (a[idx2] == a[i] - (int)pow(2, j) && idx2 != i) cnt++;
if (cnt == 2)
{
ans = 3; b[1] = a[idx2], b[2] = a[i], b[3] = a[idx];
break;
}
else if(cnt == 1)
{
ans = 2;
if (a[idx] == a[i] + (int)pow(2, j)) b[1] = a[i], b[2] = a[idx];
if (a[idx2] == a[i] - (int)pow(2, j)) b[1] = a[idx2], b[2] = a[i];
}
}
if (ans == 3) break;
}
cout << ans << endl;
if (ans == 3) cout << b[1] << " " << b[2] << " " << b[3] << endl;
else if (ans == 2) cout << b[1] << " " << b[2] << endl;
else cout << a[1] << endl;
return 0;
}