列表

详情


NC230886. D 与太阳

描述

天空中有 n 个太阳,第 i 个太阳的高度为 a_i,各个太阳的高度互不相同。D 携带了所有型号大于 1 的箭。D 可以任意选定一个大于 1 的正整数 x,代表选择了一根型号为 x 的箭,然后他会再选择一个角度 k。最终,D 会射下所有高度模 xk 的太阳。

D 的偶像是桃花,为了射日如桃花,D 需要一次性射下尽可能多的太阳。现在请回答,他最多可以一次性射下多少个太阳。

输入描述

第一行一个正整数 n

第二行 n 个正整数,第 i 个数 a_i 表示第 i 个太阳的高度。

数据保证 a_i 两两不同。

输出描述

一行一个自然数,代表 D 最多能射下多少个太阳。

示例1

输入:

4
3 6 9 12

输出:

4

说明:

在样例 1 中,D 选择 x=3k=0,然后可以射下所有太阳,因为 3\equiv6\equiv9\equiv12 \equiv0\mod 3

示例2

输入:

5
1 8 11 16 31

输出:

4

说明:

在样例 2 中,D 选择 x=5k=1,然后射下除 8 以外的四个太阳,因为 1\equiv11\equiv16\equiv31\equiv1\mod 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 824ms, 内存消耗: 82656K, 提交时间: 2021-11-28 21:17:21

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<cstring>
#include<map>
#define ll long long 
const int maxn=5e6+7;
using namespace std;
map <ll,ll>	ma,vis;
ll a[maxn],visit[maxn]={0},su[maxn]={0},ans=0,n,num[maxn];
ll read() {	//快读 
    ll s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
    return s*w;
}
ll fun()
{	long long i,j,k;
	for(i=0;i<=maxn;i++)	visit[i]=0;
	k=0;visit[1]=1;
	for(i=2;i<=maxn;i++)	
	{	if(!visit[i])
		{	su[++k]=i;
			for(j=i*i;j<=n;j+=i)	visit[j]=1;	//筛掉非素数 
		}
	}
	return k;	//返回素数的个数 
}
void getans(ll x)
{	if((double)x*ans*(ans-1)/2>1e13) return;
	if(vis[x]) return;
	vis[x]=1;
	ll i,j,k;
	if(x<=1e6)
	{	for(i=1;i<=n;i++)	num[a[i]%x]++;	
		for(i=1;i<=n;i++) 
		{	if(num[a[i]%x]>ans) ans=num[a[i]%x];
			num[a[i]%x]=0;
		}	
		return;
	}
	for(i=1;i<=n;i++)	ma[a[i]%x]++;
	for(i=1;i<=n;i++)	if(ma[a[i]%x]>ans) ans=ma[a[i]%x];
	ma.clear();
}
int main()
{	ll i,j,k,T=20,x,y,d;
	n=read();
	for(i=1;i<=n;i++)	a[i]=read();
	srand((ll)time(0));
	getans(2);
	k=fun();
	while(T--)
	{	x=rand()%n+1;
		y=rand()%n+1;
		d=abs(a[x]-a[y]);
		for(i=1;i<=k&&su[i]<=d;i++)
		{	if(d%su[i]==0)
			{	getans(su[i]);
				while(d%su[i]==0) d/=su[i];
			}	
		}
		if(d>1)	getans(d);
	}
	cout<<ans<<endl;
	return 0;
} 

上一题