CF988D题解

题目大意

题目传送门

题意:给你有 n n n 个数字的一个数列,问最多有多少个数字他们 两两的差是 2 的幂次方数

思路

首先,我们想个数能不能组成一个满足题目要求的序列,答案是肯定的。(直接输出 a 1 a_1 a1 不就彳亍了吗)

再想个数彳亍不彳亍。看看样例:

输入 #1

6
3 5 4 7 10 12

输出 #1

3
7 3 5

举个栗子: 3 3 3 5 5 5 之间差距是 2 2 2,即 2 1 2^1 21

再来看个数的,样例输出就已经给了。

个数,还是举个栗子:

输入:
1 2 3 4

发现如果是个数, 1 1 1 4 4 4 相差 3 3 3,并不是 2 2 2 的次方,发现不行。

证明一下:

令四个数为 a , b , c , d a,b,c,d a,b,c,d,则:

∣ a − b ∣ = 2 x 0 , ∣ b − c ∣ = 2 x 1 , ∣ c − d ∣ = 2 x 2 |a-b|=2^{x_0}, |b-c|=2^{x_1}, |c-d|=2^{x_2} ab=2x0,bc=2x1,cd=2x2

此时需要满足两两之差为 2 2 2 的次方,则 x 0 = x 1 = x 2 x_0=x_1=x_2 x0=x1=x2

∣ a − c ∣ = 2 x 0 + 1 , ∣ b − d ∣ = 2 x 1 + 1 |a-c|=2^{x_0+1}, |b-d|=2^{x_1+1} ac=2x0+1,bd=2x1+1

∣ a − d ∣ = 3 × 2 x 0 ≠ 2 k |a-d|=3 \times 2^{x_0} \ne 2^k ad=3×2x0=2k

所以,可以满足题目要求的序列的元素个数只能输 1 , 2 , 3 1, 2, 3 1,2,3 个。

代码核心部分:

for (int i = 1;i <= n;i++) //枚举3个数组成的序列 
{
	for (int j = 0;j <= 30;j++)
	{
		int w = sum[j]; //w获取了2的j次方
		if (s.count(a[i]+w) >= 1 && s.count(a[i]+2*w) >= 1) //判断是否有一个满足条件的序列 
		{
			printf("3\n%lld %lld %lld",a[i],a[i]+w,a[i]+2*w); //可以输出啦 
			return 0; //直接结束程序 
		}
	}
}

最后,附上我的 AC 代码:

#include <bits/stdc++.h> //万能头 
#define int long long //可能会超int 
using namespace std;
int n;
int a[200010];
set <int> s; //用集合去存储,会自动去重和排序 
int sum[40]; //sum[i]表示2的i次方 
signed main() //这里注意是signed 
{
	sum[0] = 1; //这里初始化是为了优化pow函数 
	for (int i = 1;i <= 30;i++)
	{
		sum[i] = sum[i-1] * 2;
	}
	scanf("%lld",&n); //以防万一,就用scanf吧 
	for (int i = 1;i <= n;i++)
	{
		scanf("%lld",&a[i]);
		s.insert(a[i]); //将a[i]加入集合 
	}
	for (int i = 1;i <= n;i++) //枚举3个数组成的序列 
	{
		for (int j = 0;j <= 30;j++)
		{
			int w = sum[j]; //w获取了2的j次方
			if (s.count(a[i]+w) >= 1 && s.count(a[i]+2*w) >= 1) //判断是否有一个满足条件的序列 
			{
				printf("3\n%lld %lld %lld",a[i],a[i]+w,a[i]+2*w); //可以输出啦 
				return 0; //直接结束程序 
			}
		}
	}
	for (int i = 1;i <= n;i++) //枚举2个数组成的序列
	{
		for (int j = 0;j <= 30;j++)
		{
			int w = sum[j]; //w获取了2的j次方
			if (s.count(a[i]+w) >= 1) //判断是否有一个满足条件的序列 
			{
				printf("2\n%lld %lld",a[i],a[i]+w); //可以输出啦 
				return 0; //直接结束程序 
			}
		}
	}
	printf("1\n%lld",a[1]); //最后,如果3个或2个都不行,那就随便输出原数列中的一个数 
	return 0;
}

相关推荐

  1. CF988D题解

    2024-05-10 21:32:03       11 阅读
  2. 题解CF1923D(Slimes)

    2024-05-10 21:32:03       22 阅读
  3. 题解CF1946D(Birthday Gift)

    2024-05-10 21:32:03       10 阅读
  4. codeforce#938 (div3) 题解

    2024-05-10 21:32:03       14 阅读
  5. CF1902 B Getting Points 题解

    2024-05-10 21:32:03       47 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-10 21:32:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-10 21:32:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-10 21:32:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-10 21:32:03       20 阅读

热门阅读

  1. React 第二十八章 前端框架

    2024-05-10 21:32:03       9 阅读
  2. 按键精灵写的有点失败了

    2024-05-10 21:32:03       9 阅读
  3. 关于学习与智慧

    2024-05-10 21:32:03       8 阅读
  4. 说说SpringBoot自动配置原理

    2024-05-10 21:32:03       13 阅读
  5. thinkphp5 中路由常见的使用方法

    2024-05-10 21:32:03       12 阅读
  6. spring的核心详解

    2024-05-10 21:32:03       12 阅读
  7. office 官方下载地址

    2024-05-10 21:32:03       9 阅读
  8. Gradle设置引用的JAR包不编译到APK中

    2024-05-10 21:32:03       11 阅读