1246. 等差数列(数论,gcd)
https://www.acwing.com/problem/content/1248/
求最短的序列,我们知道整个序列的其中几个数
数列不确定,公差不确定,需要确定参数
总项数为(数列末端-数列首端)/d 求出中间有多少个d, 然后再加1就得到总项数了
要使这个公式最小,那么数列末端要尽可能小,数列首端要尽可能大,数列的公差也要最大,
由于要求最小项数,那么数列末端也就是Amax,数列首端也就是Amin
那么就可以确定数列首端,即a[1]了,那么给出的几个数都是这样组成的: a[1] + nd
那么它们与a[1]的差就是d的倍数,需要满足d最大,那么就是要在这些差中取最大公约数
关于这题的思路
感觉这些比较难想到的题都可以采用逆向思维去想,关键是要列出(数列末端-数列首端)/d+1这个式子,分析分母何时最大,分子何时最小,是怎么想到要求最大公约数的
比如说:求一个d,d一定是满足每个数与a[1]的差的约数的,反过来想,如果这个d已经是所有差的约数了,那么输入给出的这几个数,必定是这个最短的数列里的几个数
即最短数列一定包含给出的几个数,但是这个最短数列还不一定是最短,得让这个d最大才是最短的数列,要满足这个数列包含输入的几个数,就要保证d是所有数的约数,且最大,即求最大公约数
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
int a[N],n;
int d=0;
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a ;
}
int main()
{
cin >> n;
for(int i=1;i<=n;i++) cin >> a[i];
sort(a+1,a+n+1);
for(int i=2;i<=n;i++) d=gcd(d,a[i]-a[1]);
if(d==0) cout << n << endl;
else cout << (a[n]-a[1])/d+1 << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效