Cod sursa(job #918660)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 19 martie 2013 02:26:47
Problema Balans Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.94 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <deque>
#include <algorithm>
#include <numeric>
#include <limits>
#include <iterator>

#define MAX_SIZE 305

using namespace std;

typedef deque<pair<long long, short> > BalansDeq;

static const long long MinLongLong = numeric_limits<long long>::min();

static long long mat[MAX_SIZE][MAX_SIZE];
static long long subArray[MAX_SIZE];

void PushIntoDeq(BalansDeq& deq, long long val, short pos)
{
    while (!deq.empty() && deq.back().first >= val)
    {
        deq.pop_back();
    }
    
    deq.push_back(make_pair(val, pos));
}

int main()
{
    int N, M, R, C;
    fstream fin("balans.in", fstream::in);
    fstream fout("balans.out", fstream::out);
    
    long long right = 0LL;
    long long left = 0LL;
    
    fin >> N >> M >> R >> C;
    //cout << N << " " << M << " " << R << " " << C << endl;
    
    if (R == 0)
    {
        R = 1;
    }
    if (C == 0)
    {
        C = 1;
    }
    
    const int slidingWindowSize = M - C;
    const long long precision = 10000LL;
    
    for (int i=1; i<=N; ++i)
    {
        for (int j=1; j<=M; ++j)
        {
            fin >> mat[i][j];
            
            mat[i][j] *= precision;
            mat[N + i][j] = mat[i][j];
            
            right = max(right, mat[i][j]);

            //mat[i][j] += mat[i-1][j];
        }
        memcpy(&mat[i][M+1], &mat[i][1], M*sizeof(long long));
    }
    
    right *= 150;
    
    for (int i=1; i<=2*N; ++i)
    {
        for (int j=1; j<=M; ++j)
        {
            mat[i][j] += mat[i-1][j];
        }
        memcpy(&mat[i][M+1], &mat[i][1], M*sizeof(long long));
    }
    
    /*for (int i=1; i<=2*N; ++i)
    {
        for (int j=1; j<=2*M; ++j)
        {
            cout << mat[i][j] << " ";
        }
        
        cout << endl;
    }
    cout << endl;*/
    
    ostream_iterator<long long> itOut(cout, " ");
    
    //cout << MinLongLong << endl << endl;

    long long maxBalans = 0;
    long long step = 10;
    
    while (right - left >= step)
    {
        maxBalans = left + (right - left) / 2;
        long long maxSubSeq = MinLongLong;

        for (int i=0; i<=N; ++i)
        {
            for (int l=R; l<=N; ++l)
            {
                for (int j=1; j<=2*M; ++j)
                {
                    subArray[j] = (mat[i+l][j] - mat[i][j]) - l*maxBalans;
                }
                
                for (int j=1; j<=2*M; ++j)
                {
                    subArray[j] += subArray[j-1];
                }

                BalansDeq deq;
                deq.push_back(make_pair(0LL,0));
                
                for (int j=1; j<=2*M - C; ++j)
                {
                    PushIntoDeq(deq, subArray[j], j);
                    if (deq.front().second < j - slidingWindowSize)
                    {
                        deq.pop_front();
                    }

                    if (subArray[j+C] - deq.front().first > maxSubSeq)
                    {
                        maxSubSeq = subArray[j+C] - deq.front().first;
                    }
                    
                    if (maxSubSeq >= step) goto evaluate;
                }
                
                /*copy(subArray, subArray + 2*M + 1, itOut);
                cout << endl;
                cout << maxSubSeq << endl;*/
                
                //getchar();
            }
        }
    
    evaluate:
        if (maxSubSeq >= step)
        {
            left = maxBalans + step;
        }
        else if (maxSubSeq < step)
        {
            right = maxBalans - step;
        }

        //cout << maxBalans << endl;
    }
    
    //maxBalans /= load;
    
    float fMaxBalans = maxBalans / precision + (float)(maxBalans % precision) / precision;
    
    fout.precision(3);
    fout << fixed << fMaxBalans << "\n";
    
    return 0;
}