Cod sursa(job #963150)

Utilizator ericptsStavarache Petru Eric ericpts Data 16 iunie 2013 17:54:41
Problema Balans Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <cstdio>
#include <algorithm>
#include <deque>
using namespace std;

int n,m;
int r,q;
const int MAX_N = 155;
const double EPS = 1e-9;
const double INF = 1e17;
int orig[MAX_N][MAX_N];
int A[MAX_N*3][MAX_N*3];
double S[MAX_N*3][MAX_N*3];
double partial[MAX_N*3];

int max_val;

deque<int> D;

void place(int dx,int dy)
{
    char 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 double & offset)
{
    D.clear();
    double ret = -INF;
    int each = line2 - line1 + 1,i,cpl,limit;
    for(i = 1 ; i <= 3*m ; ++ i)
        partial[i] = partial[i-1] + S[line2][i] - S[line1-1][i] - offset * each;

    for(i = q ; i <= 3*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 double & offset)
{

    int i,j;

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

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

        if(i + step <= max_val * 1e4 && acceptable((i+step)/1e4))
            i += step;
    return i;
}

int main()
{
    freopen("balans.in","r",stdin);
    freopen("balans.out","w",stdout);
    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]);
        if(orig[i][j] > max_val)
            max_val = orig[i][j];
    }

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

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

    printf("%f",bs()/1e4);
    return 0;
}