题目大意:告诉有n棵树及其位置,求最少需要移动多少棵树能够使得每2棵树之间的距离相等
解题思路:暴力!因为n(<= 40)比较小而且至少有两棵树是不用动的,我们直接暴力枚举起点以及其后另外一点,然后枚举两棵树之间树的数目,算好间距,模拟即可。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>
using namespace std;
const int maxn = 40+10;
long long num[maxn];
int main()
{
int t,n;
int ans;
map<long long,int> mp; //记录每个位置树的数目
int cases = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
mp.clear();
for(int i = 1; i <= n; i++)
{
scanf("%lld",&num[i]);
if(mp.find(num[i]) == mp.end())
mp[num[i]] = 1;
else
mp[num[i]]++;
}
if(n == 2)
{
printf("Case #%d: 0\n",cases++);
continue;
}
int ans = n;
for(int i = 1; i <= n; i++)
{
ans = min(ans,n-mp[num[i]]);
for(int j = i+1; j <= n; j++)
{
long long dis = (num[i]-num[j]) > 0 ? (num[i]-num[j]) : (num[j]-num[i]);
if(!dis) continue;
for(int k = 0; k <= n-2; k++) //在2棵树之间放的树的数目
{
if(dis % (k+1)) continue; //距离不能整除
long long d = dis/(k+1); //d为公差
long long tmp = min(num[i],num[j]);
int cnt = 0;
for(int l = 0; l <= k+1; l++) //从第0棵树开始找(tmp位置)
{
if(mp.find(tmp) != mp.end()) cnt++;
tmp += d;
}
ans = min(ans,n-cnt);
}
}
}
printf("Case #%d: %d\n",cases++,ans);
}
return 0;
}