Codeforces 988D 題解

<988D>

題意:

給定若干個數,問在其中挑選幾個數組成一個集合,使得集合中任意以兩個數a, b(a > b)的差值均爲2^n。

思路:

這題要先找規律,這個規律就是,集合中的元素最多有3個,證明如下:

假設集合內目前只有三個元素:x,y,z 且 x < y < z

則根據題意,有如下關係:

z - y = 2^a (1)

y - x = 2^b (2)

z - x = 2^c (3)

所以由 (1)式 + (2)式,再與 (3)式聯立,得 z - x = 2^a + 2^b = 2^c,由此可得,當且僅當

2^c = 2 * 2^b = 2 * 2^a 時上述等式成立,即 a = b = c - 1;

所以由 a = b, 得 2^a = 2^b,即 z - y = y - x,所以 x,y,z構成等差數列,

由上可知,當集合中有四個元素的時候,x < y < z < k 時,顯然就不成立了,因爲你要滿足從中挑出的任意三個元素滿足等差數列,比如 <x, y, k> 或 <x, z, k>時就不成立了,因爲x, y, z, k滿足等差數列,且公差不能爲0,所以它的三元組子集就未必滿足構成等差這個條件了。

找到這個規律以後就好辦了,存進集合set中,然後在1~2e9中枚舉2^n,再加到集合元素a[i]上,看有幾個在集合中即可,如果夠不成等差數列,即只有一個元素的時候,那就輸出a[1]就好了。

本人AC代碼:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
map <int, int> mp;
vector <int> vec;
queue <int> qua;
set <ll> sst;
int n;
ll a[maxn];

int main() {
	cin >> n;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
		sst.insert(a[i]);
	}
	for(int i = 1; i <= n; i++) {
		for(ll j = 1; j <= 2e9; j *= 2) {
			if(sst.count(a[i] + j) && sst.count(a[i] + 2 * j)) {
				puts("3");
				printf("%I64d %I64d %I64d\n", a[i], a[i] + j, a[i] + 2 * j);
				return 0;
			}
		}
	}
	for(int i = 1; i <= n; i++) {
		for(ll j = 1; j <= 2e9; j *= 2) {
			if(sst.count(a[i] + j)) {
				puts("2");
				printf("%I64d %I64d\n", a[i], a[i] + j);
				return 0;
			}
		}
	}
	puts("1");
	cout << a[1] << endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章