Codeforces Round #486 (Div. 3)988D. Points and Powers of Two
传送门:http://codeforces.com/contest/988/problem/D
题意:
在一堆数字中,找出尽量多的数字,使得这些数字的差都是2的指数次。
思路:
可以知道最多有三个,差值为2、4;或者是a[i],a[i]+2的k次,a[i]-2的k次;
两个就直接找。
一个随便输出一个。
ac代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <map> #include <set> #include <queue> #include <list> #include <iterator> #include <cmath> using namespace std; #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << "\n"; #define pb push_back #define pq priority_queue #define Pll pair<ll,ll> #define Pii pair<int,int> #define fi first #define se second #define OKC ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) typedef long long ll; typedef unsigned long long ull; /*-----------------show time----------------*/ const int maxn = 2e5+9; int n; ll a[maxn]; map<ll,int>mp; ll ksm (int a,int b) { ll res = 1ll; while(b) { if(b&1)res = res * a; a = a*a; b>>=1; } return res; } int main(){ scanf("%d", &n); // cout<<ksm(2,1)<<endl; for(int i=1; i<=n; i++) { scanf("%lld" , &a[i]); if(!mp.count(a[i]))mp[a[i]] = 0; mp[a[i]]++; } int flag2 = 0,flag1 = 0; ll ans,jie; for(int i=1; i<=n&&flag1==0; i++) { if(mp.count(a[i] + 2)&&mp.count(a[i]+4)) { flag2 = 1; ans = a[i]; break; } for(int j=0; j<32; j++) { if(mp.count(a[i]+ksm(2,j))&&mp.count(a[i]-ksm(2,j))) { ans = a[i]; jie = j; flag1 = 1; break; } } } if(flag2) { printf("3\n%lld %lld %lld\n",ans,ans+2,ans+4); return 0; } if(flag1) { printf("3\n%lld %lld %lld\n",ans,ans+ksm(2,jie),ans-ksm(2,jie)); return 0; } for(int i=1; i<=n && flag2 == 0; i++) { for(int j=0; j<32; j++) { if(mp.count(a[i]+ksm(2,j))) { ans = a[i]; jie = j; flag2 = 1; break; } } } if(flag2) { printf("2\n%lld %lld\n",ans,ans+ksm(2,jie)); return 0; } printf("1\n%lld\n",a[1]); }
skr