SRM486 Div2 Hard(1000) CrazyLine
中央値xより低い生徒と高い生徒を交互に並べるとそれぞれの生徒のcrazinessへの寄与は2abs(heights[i]-x)。ただし両端の生徒はこれより小さいので、中央値付近の生徒を両端に置く。生徒数が奇数の場合は選び方が2通りあるので、よりcrazinessの大きい方を答えにする。
#include <vector> #include <algorithm> using namespace std; class CrazyLine{public: int maxCrazyness( vector <int> heights ) { int n = (int)heights.size(); if ( n == 1 ) return 0; sort( heights.begin(), heights.end() ); int ans = 0; if ( n % 2 == 0 ) { for ( int i=0; i<n/2-1; i++ ) ans += ( heights[n/2-1] - heights[i] ) * 2; ans += heights[n/2] - heights[n/2-1]; for ( int i=n/2+1; i<n; i++ ) ans += ( heights[i] - heights[n/2-1] ) * 2; } else { int ans1 = 0; for ( int i=0; i<n/2; i++ ) ans1 += ( heights[n/2] - heights[i] ) * 2; ans1 += heights[n/2+1] - heights[n/2]; for ( int i=n/2+2; i<n; i++ ) ans1 += ( heights[i] - heights[n/2] ) * 2; int ans2 = 0; for ( int i=0; i<n/2-1; i++ ) ans2 += ( heights[n/2] - heights[i] ) * 2; ans2 += heights[n/2] - heights[n/2-1]; for ( int i=n/2+1; i<n; i++ ) ans2 += ( heights[i] - heights[n/2] ) * 2; ans = max( ans1, ans2 ); } return ans; }};