C 언어 연습은 두 번째 세트를 행사

평등 펜

N 개별 원 각각이 펜 인공 지능. 각 사람은, 주변의 이웃 사람들에게 에너지가 사람 1 당 펜을 전달하여 소비 할 때마다 펜을 전달할 수 있습니다. 찾는 모든 사람들에게 펜 최소 에너지의 동일한 수를 제공합니다.

입력 형식 :

제 라인 정수 N, 수 (데이터의 30 %, N <= 1000; 100 % 데이터, N <= 1E6 명).

다음 N 라인 정수 인공 지능 각 라인.

출력 형식 :

펜 모든 최소 에너지 평등을 나타내는 출력 할 정수. (대답은 그 64 비트 정수 매장을 확보 할 수 있습니다)

샘플 입력 :

4
1
2
5
4

샘플 출력 :

4

알고리즘 설명

욕심쟁이 알고리즘

여기에 게시 된 링크의 자세한 설명은 다음의 핵심 알고리즘에 대한이 질문에 잠시 넣어.
우선, 아이 사탕 나는 사람 것이다 소정의 제 I-1 사이 개별 사탕 (-xi), 제 i + 1 개 개인 사이 캔디 + 1 내지 제를 수용 한 사람의 손 난 후 AVE 사탕 (XI의 양극 및 음극, 즉 음극과, N 개의 가정 된 송신 방향이 정확 나타냄) 인공 지능 사이가 + 사이 + 1 AVE가 =
사탕 조각 아이 시작 전 어린이 지정된 가정 사이의 i 번째 자식을 나타낸다 처음에 I-1 번째 하위 사이 사탕 조각 사이 <0, I-1 아이 사이를 참조하여 설명하면, i 번째 자식 사탕 조각, 특히 상기 X1은 N 아이 캔디에 아이를 나타낸다 수. 최종 대답은 ANS이다 그래서 = | X1 | + | X2 | + | X3 | + ... + | Xn에 |. 첫 번째 자식을 위해, 그는 n 번째 자식 X1 사탕 조각을 준 사탕 조각이 A1-X1 남아 있지만, 처음 두 아이들은 그에게 X2 사탕 조각, 마지막 남은 A1-X1 + X2 사탕 조각을 준 때문이다. A1-X1 + X2 = AVE : 질문의 의미에 따르면, 최후의 식을 구 사탕 AVE의 개수와 동일 .
마찬가지로, 제 2 아이 거기 A2-X2 + X3 = AVE. 마지막으로, 우리는 방정식, n은 변수의 총 N을 얻을 수 있지만 전 N-1 방정식이 사실 때문에, 마지막 식으로 추론 할 수 있기 때문에 단지 N-1 방정식 유용합니다.
표현 사이의 응답이 직접 해소 할 수 없지만, 다른 X1을 사용할 수 있지만,이 문제는 하나 개의 변수에 극값의 문제가된다. (X1의 X2, X3, .... XN로 표시됨)
제 아이 A1-X1 + X2 = 대해 AVE -> X2 = AVE-A1 + X1 = X1-C1 ( C1 = A1-AVE는 가정 )과 유사한 다음

처음 두 어린이, A2-X2 + X3 = AVE -> X3 = AVE-A2 + X2 = 2ave-A1-A2 + X1 = X1-C2

처음 세 어린이, A3-X3 + X4 = AVE -> X4 = AVE-A3 + X3 = 3ave-A1-A2-A3 + X1 = X1-C3

n 번째 아이 ...... 한 - X1 내지 Xn + = AVE.

우리 사이의 절대 값을 희망 가능한 한 작게, 즉 | X1 | + | X1-C1 | + | X1-C2 | + ... + | X1-CN-1 | 가능한 한 작게한다. 공지 사항 | X1-CI는 | 질문가되도록 기하학적 의미는, 숫자 선에 거리에 CI 포인트 X1입니다 : 수 선 N 주어진 (참고 N 포인트가 0으로 잊지 마세요 !!) 포인트는, 자신의 거리가 가능한 점의 소형 합을 발견하고,이 점은이 숫자가 약간 입증, 중간 점이다. (| X1-0 | + | X1-C1 | + | X1-C2 | + ... + | X1-CN-1 |)

다음 코드는

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
long long int a[1000005],s[1000005];
int main()
{
    long long int n,i,store=0,ave,temp;
    long double flag,res=0;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>a[i];
        store+=a[i];
        s[i]=store;//A1加到Ai 
    }
    ave=store/n;//取平均数 
    s[0]=0;
    for(i=1;i<=n-1;i++) s[i]-=i*ave;//Ci 
    sort(s,s+n);
    if(n%2!=0) flag=s[n/2];
    else flag=1.0*(s[n/2]+s[n/2-1])/2;
    for(i=0;i<n;i++) res+=fabs(flag-1.0*s[i]);
    temp=res;
    cout<<temp;
    return 0;
}

주의 사항

· 먼저 알고리즘에 관심을 지불하는 것입니다. 이 알고리즘은 질문 난하지 않습니다. . . 모든 I의 노하우 알고리즘의 욕심 유형 (나는 5555 그래서 쓰레기 해요을)입니다. 온라인 블로그 lvhang 쓰기에 직접 검색 결과, 검색 항목을 직접? ? ? 그리고 로스 기본 문제의 계곡에서 동일한 찾아 그것을 따르십시오. 주제 문제 해결책

· 다음은 선택의 데이터 유형입니다. 이 중앙값을 평가할 때 오차의 결과 (예를 들어, 심지어 중간의 수와 나눌 수 없습니다 합이 필요한 두 의해 분할 요청 데이터) 정밀도의 정수 데이터 사용이 손실 될 부동 소수점 데이터의 사용을 필요로한다. 이것은 매우 치명적입니다.

·이 수 n의 평균을 찾을 필요가이고, n은 숫자입니다! ! ! , | X1 | + | X1-C1 | + | X1-C2 | + ... + | X1-CN-1 |, 즉 | X1-0 | + | X1-C1 | + | X1-C2 | + ... + | X1-CN-1 | 0이 누출되지.

출력 형식 당신은 (대상 예제가 출력 4 테스트 할 때 사용이 두 배로 이유는 무엇입니까?) 데이터 출력 정수 사용해야합니다

출력 형식의 마지막 문장 : 대답은 64 비트 정수 저장을 보장 할 수 있습니다, 선택의 데이터 유형은 비교적 큰 열려 있어야합니다. 어떤에서 나는 긴 침을 찾고 버그를 발견하기 만 나중에 찾기 위해 최소 한 시간을 보냈습니다.

즉, 그것은 AC입니다. . . . .

추천

출처www.cnblogs.com/031902522ycy/p/12393284.html