1. 程式人生 > 其它 >Arithmetic Operations(CF 1654 E)

Arithmetic Operations(CF 1654 E)

傳送門

題目大意

給你一個序列,問最少的把一個數改成其他任意數的運算元使得這個序列變成一個等差數列。\((1\leq n\leq10^5,1\leq a_i\leq10^5)\)

思路

很容易就能想到把這個問題轉化為一個二維平面上求一條直線能經過最多點的問題,但是由於縱座標會很大,所以不能直接暴力列舉斜率,但是我們又能想到當斜率很大時,肯定不會有很多點被經過,所以對於小斜率我們可以直接暴力列舉,然後對於大斜率,我們兩兩之間進行列舉,然後就能輕鬆\(AC\)了。不過至於什麼是小斜率,那就設的稍微小一點,\(20\)~\(50\)之間都行吧。

程式碼

#include<bits/stdc++.h>
using namespace std;
const int t=30;
int a[100005];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int ans=0;
	for(int i=-t;i<=t;i++)
	{
		map<int,int>cnt;
		for(int j=1;j<=n;j++)
			ans=max(ans,++cnt[a[j]-i*j]);
	}
	for(int i=1;i<=n;i++)
	{
		map<int,int>cnt;
		int r=100000/t;
		for(int j=i+1;j-i<=r&&j<=n;j++)
		{
			int d=a[j]-a[i];
			if(d%(j-i))continue;
			d/=(j-i);
			ans=max(ans,++cnt[d]+1);
		}
	}
	printf("%d\n",n-ans);
	return 0;
}