Cod sursa(job #861189)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 21 ianuarie 2013 09:45:44
Problema Plantatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.27 kb
#include <fstream>
#include <iostream>
#include <cstdlib>
 
#define nullptr NULL
 
using namespace std;
 
typedef unsigned char uint8;
     
template<uint8 N, char prev>
struct LookupTable;
 
template<char prev>
struct LookupTable<255, prev>
{
    LookupTable() :
        value(prev)
    {}
    char value;
};
 
template<uint8 N, char prev>
struct LookupTable
{
    LookupTable() :
        value(prev)
    {}
 
    char value;
    LookupTable<N+1, prev + (((N+1) & N) == 0)> next;
};
 
template<char prev>
struct LookupTable<0, prev>
{
    LookupTable() :
        value(prev)
    {}
    char value;
    LookupTable<1, 0> next;
};
 
class Log2Helper
{
public:
 
    static int Log2Of(int n)
    {
        /*if (ptr[n >> 24] > -1)
        {
            return ptr[n >> 24] + 24;
        }
        else if (ptr[n >> 16] > -1)
        {
            return ptr[n >> 16] + 16;
        }
        else*/ if (ptr[n >> 8] > -1)
        {
            return ptr[n >> 8] + 8;
        }
         
        return ptr[n];
    }
 
    static LookupTable<0, -1> Log2LookupTable;
    static char* ptr;
};
 
LookupTable<0, -1> Log2Helper::Log2LookupTable;
char* Log2Helper::ptr = reinterpret_cast<char*>(&Log2LookupTable);
 
class CMatrixNxN
{
public:
 
    CMatrixNxN(int n) :
        m_iSize(n),
        m_pRawMatrix(new int[n*n])
    {}
     
    CMatrixNxN(const CMatrixNxN& other, int skipAhead)
    {
        m_iSize = other.size() - skipAhead;
         
        m_pRawMatrix = new int[m_iSize*m_iSize];
         
        for (int i=0; i<m_iSize; ++i)
        {
            for (int j=0; j<m_iSize; ++j)
            {
                (*this)[i][j] = std::max(std::max(other[i][j], other[i][j+skipAhead]),
                                         std::max(other[i+skipAhead][j], other[i+skipAhead][j+skipAhead]));
            }
        }
    }
     
    int* operator [] (int index)
    {
        return &m_pRawMatrix[index * m_iSize];
    }
     
    const int* operator [] (int index) const
    {
        return &m_pRawMatrix[index * m_iSize];
    }
     
    int size() const
    {
        return m_iSize;
    }
     
    ~CMatrixNxN()
    {
        if (m_pRawMatrix != nullptr)
        {
            delete m_pRawMatrix;
        }
    }
     
    void print() const
    {
        for (int i=0; i<m_iSize; ++i)
        {
            for (int j=0; j<m_iSize; ++j)
            {
                cout << (*this)[i][j] << " ";
            }
            cout << endl;
        }
    }
     
private:
    int m_iSize;
    int *m_pRawMatrix;
};
 
typedef CMatrixNxN* PCMatrixNxN;
 
int Query(const PCMatrixNxN* vppPlantation, int row, int col, int size)
{
    const int log2OfSize = Log2Helper::Log2Of(size);
     
    int max1 = std::max((*vppPlantation[log2OfSize])[row][col], (*vppPlantation[log2OfSize])[row][col + size - (1<<log2OfSize)]);
    int max2 = std::max((*vppPlantation[log2OfSize])[row + size - (1<<log2OfSize)][col], (*vppPlantation[log2OfSize])[row + size - (1<<log2OfSize)][col + size - (1<<log2OfSize)]);
     
    return std::max(max1, max2);
}
 
int main()
{
    int n, m;
    fstream fin("plantatie.in", fstream::in);
    fstream fout("plantatie.out", fstream::out);
     
    fin >> n >> m;
    //cout << n << " " << m << endl;
     
    PCMatrixNxN* vppPlantation = new PCMatrixNxN[Log2Helper::Log2Of(n) + 1];
 
    vppPlantation[0] = new CMatrixNxN(n);
     
    for (int i=0; i<n; ++i)
    {
        for (int j=0; j<n; ++j)
        {
            fin >> (*vppPlantation[0])[i][j];
             
            //cout << (*vppPlantation[0])[i][j] << " ";
        }
        //cout << endl;
    }
    //cout << endl;
 
    for (int i=1; (1<<i)<=n; ++i)
    {
        vppPlantation[i] = new CMatrixNxN(*vppPlantation[i-1], 1<<(i-1));
        //vppPlantation[i]->print();
        //cout << endl;
    }
     
    for (int i=0; i<m; ++i)
    {
        int row, col, size;
        fin >> row >> col >> size;
         
        //cout << row-1 << " " << col-1 << " " << size << endl;
        fout << Query(vppPlantation, row-1, col-1, size) << "\n";
    }
     
    /*for (int i=0; i<256; ++i)
    {
        cout << i << "  " << Log2Helper::Log2Of(i) << endl;
    }*/
    return 0;
}