Cod sursa(job #963167)

Utilizator ericptsStavarache Petru Eric ericpts Data 16 iunie 2013 18:32:32
Problema Balans Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <cstdio>
#include <algorithm>
#include <deque>
#include <fstream>
#include <iomanip>


using namespace std;
typedef long long LL;
int n,m;
int r,q;
const int MAX_N = 155;
int orig[MAX_N][MAX_N];
int A[MAX_N*2][MAX_N*2];
LL S[MAX_N*2][MAX_N*2];
LL partial[MAX_N*2];

const LL INF = 1LL<<60;

int max_val;

deque<int> D;

void place(int dx,int dy)
{
    int i,j;
    for(i = 1 ; i <= n ; ++ i)
        for(j = 1 ; j <= m ; ++ j)
            A[i+dx-1][j+dy-1] = orig[i][j];
}

double best(int line1,int line2,const LL & offset)
{
    D.clear();
    LL ret = -INF;
    int each = line2 - line1 + 1,i,cpl,limit;
    for(i = 1 ; i <= 2*m ; ++ i)
        partial[i] = partial[i-1] + S[line2][i] - S[line1-1][i] - offset * each;

    for(i = q ; i <= 2*m ; ++ i){
        cpl = i-q;
        limit = i - m;
        while(!D.empty() && D.front() < limit)D.pop_front();
        while(!D.empty() && partial[D.back()] > partial[cpl])D.pop_back();
        D.push_back(cpl);
        ret = max(ret,partial[i] - partial[D.front()]);
    }

    return ret;
}
bool acceptable(const LL & offset)
{

    int i,j;
    for(i = 1 ; i + r - 1 <= 2 * n ; ++ i)
        for(j = i + r - 1 ; j <= i + n - 1 ; ++ j)
            if(best(i,j,offset) >= 0)
                return 1;
    return 0;
}

int bs()
{
    int i,step;
    for(step = 1 ; step < max_val ; step <<= 1);
    for(i = 0 ; step ; step >>= 1)

        if(i + step <= max_val && acceptable((i+step)))
            i += step;
    return i;
}

int main()
{
    freopen("balans.in","r",stdin);
    ofstream out("balans.out");
    int i,j;

    scanf("%d%d%d%d",&n,&m,&r,&q);

    for(i = 1 ; i <= n ; ++ i)
        for(j = 1 ; j <= m ; ++ j){
        scanf("%d",&orig[i][j]);
        orig[i][j] *= 1e3;

        if(orig[i][j] > max_val)
            max_val = orig[i][j];
    }

    for(i = 1 ; i < 2 * n ; i += n)
        for(j = 1 ; j < 2 * m ; j += m)
            place(i,j);

    for(i = 1 ; i <= 2 * n ; ++ i)
        for(j = 1 ; j <= 2 * m ; ++ j)
            S[i][j] = S[i-1][j] + A[i][j];

    out << fixed << setprecision(3) << bs()/1e3;
    return 0;
}