题目
https://vjudge.net/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-A1633
思路
pos 中的最大值,设为 maxx ,则 maxx 为解的最优间隔,枚举所有相邻两点的距离,求解需要加点的个数
代码
# include<iostream>
# include<algorithm>
#include <string>
#define MAXX 100005
using namespace std;
int n;
int a[MAXX], pre[MAXX], l[MAXX], r[MAXX];
int pos[MAXX];
int gcd(int aa, int b)
{
int t;
while (b)
{
t = b;
b = aa % b;
aa = t;
}
return aa;
}
int main()
{
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
sort(a, a + n);
for (int i = 1; i < n; ++i)
{
pre[i] = a[i] - a[i - 1];
}
//找每去除一个间隔的最大公约数
l[1] = pre[1];
for (int i = 2; i < n; i++)
{
l[i] = gcd(l[i - 1], pre[i]);
}
r[n - 1] = pre[n - 1];
for (int i = n - 2; i > 0; i--)
{
r[i] = gcd(pre[i], r[i + 1]);
}
pos[1] = r[2];
pos[n - 1] = l[n - 2];
for (int i = 2; i < n - 1; i++)
{
pos[i] = gcd(l[i - 1], r[i + 1]);
// cout<<pos[i]<<' ';
}
int mmax = pos[1];
for (int i = 2; i < n; i++)
{
if (pos[i] > mmax)
mmax = pos[i];
}
// cout<<mmax<<endl;
int ans = 0;
int f = 0, ms = 0;
for (int i = 1; i < n; i++)
{
if (pre[i] % mmax != 0)
{
f++;
continue;
}
ans += pre[i] / mmax - 1;
ms = max(ms, pre[i] / mmax - 1); //找出最大的一个,然后不拆分这一段
}
if (!f)
ans -= ms;
cout << ans << endl;
return 0;
}
注意
命名变量的时候,名字可以长一些,要不然找错误的时候不好找。。。比如这次就把r写成了l,debug了好久。。。