對於這題本人剛開始的時候的想法是:先把最大兩數差的位置找到然後merge計算一個值再與一連串相同的數做merge後計算一個值比較取最大值輸出;可提交後發現不對,於是本人就搜了一下正解發現原來這題的正確解題思路是:采用數學中的中位數原理,分別把某數兩邊相鄰且不同的數存入向量容器Vector中然後排序,找到中位數計算一遍,找到計算的最大值,然後把按照輸入順序的值計算出一個總和,然後相減就是其解。
關於中位數原理本人稍微提一下:
求中位數,首先要先進行數據的排序(從小到大),然後計算中位數的序號,分數據為奇數與偶數兩種來求。排序時,相同的數字不能省略) [2]
中位數算出來可避免極端數據,代表著數據總體的中等情況。
如果總數個數是奇數的話,按從小到大的順序,取中間的那個數。
如果總數個數是偶數的話,按從小到大的順序,取中間那兩個數的平均數。
其中中位數的應用就是求與其它元素距離最小之和;本體還涉及到分治思想;好了廢話也不說多了就貼一下我的代碼吧;
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <vector>
6 #define LL __int64
7 using namespace std;
8 const int N = 100000+10;
9 int A[N];
10 int n,m;
11 int vis[N];
12 vector<int> v[N];
13 int abs(int x)
14 {
15 if (x<0) return -x;
16 else return x;
17 }
18 int main()
19 {
20 while (scanf("%d%d",&n,&m)!=EOF)
21 {
22 LL ans=0;
23 memset(vis,0,sizeof vis);
24 for (int i=1;i<=m;i++){
25 scanf("%d",&A[i]);
26 if (i>1){
27 if (A[i]!=A[i-1]){
28 v[A[i]].push_back(A[i-1]);
29 v[A[i-1]].push_back(A[i]);
30 }
31 ans+=(LL)abs(A[i]-A[i-1]);
32 }
33 }
34 LL maxn=0;
35 if (m>1)
36 for (int i=1;i<=m;i++){
37 if (vis[A[i]]) continue;
38 vis[A[i]]=1;
39 sort(v[A[i]].begin(),v[A[i]].end());
40 int r=v[A[i]].size();
41 if (r==0) continue;
42 r/=2;
43 int mid=v[A[i]][r];
44 LL t1=0;
45 LL t2=0;
46 for (int j=0;j<v[A[i]].size();j++){
47 t1+=(LL)abs(mid-v[A[i]][j]);
48 }
49 for (int j=0;j<v[A[i]].size();j++){
50 t2+=(LL)abs(A[i]-v[A[i]][j]);
51 }
52 maxn = max(maxn,t2-t1);
53 }
54 ans -= axn;
55 printf("%I64d\n",ans);
56 }
57 return 0;
58 }