對於這題本人剛開始的時候的想法是:先把最大兩數差的位置找到然後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 }