Submission #280299

#TimeUsernameProblemLanguageResultExecution timeMemory
280299KastandaArt Class (IOI13_artclass)C++11
87 / 100
111 ms12792 KiB
// M
#include<bits/stdc++.h>
#include "artclass.h"
#define ID(i, j) ((i) * (m) + (j))
using namespace std;
const int N = 505, MXN = N * N;
int n, m, R[N][N], G[N][N], B[N][N];
bool MR[MXN];
vector < int > Adj[MXN];

int SZ = 30, DF = 70;
vector < int > IGNORE = {0, 0, 0};

inline vector < int > GetMean(int i, int j)
{
        int cnt = 0;
        vector < int > Rs(3, 0);
        for (int dx = 0; dx < SZ; dx ++)
                for (int dy = 0; dy < SZ; dy ++)
                        if (i + dx >= 0 && i + dx < n && j + dy >= 0 && j + dy < m)
                        {
                                Rs[0] += R[i + dx][j + dy];
                                Rs[1] += G[i + dx][j + dy];
                                Rs[2] += B[i + dx][j + dy];
                                cnt ++;
                        }
        for (int i = 0; i < 3; i ++)
                Rs[i] /= cnt;

        for (int i = 0; i < 3; i ++)
                if (IGNORE[i])
                        Rs[i] = 0;

        return Rs;
}

inline bool Similar(int i1, int j1, int i2, int j2)
{
        vector < int > X = GetMean(i1, j1);//{R[i1][j1], B[i1][j1], G[i1][j1]};
        vector < int > Y = GetMean(i2, j2);//{R[i2][j2], B[i2][j2], G[i2][j2]};

        for (int i = 0; i < 3; i ++)
                if (abs(X[i] - Y[i]) > DF)
                        return 0;

        return 1;
}
inline void MakeGraph()
{
        for (int i = 0; i < n; i += SZ)
                for (int j = 0; j < m; j += SZ)
                {
                        if (i + SZ < n && Similar(i, j, i + SZ, j))
                        {
                                Adj[ID(i / SZ, j / SZ)].push_back(ID(i / SZ + 1, j / SZ));
                                Adj[ID(i / SZ + 1, j / SZ)].push_back(ID(i / SZ, j / SZ));
                        }
                        if (j + SZ < m && Similar(i, j, i, j + SZ))
                        {
                                Adj[ID(i / SZ, j / SZ)].push_back(ID(i / SZ, j / SZ + 1));
                                Adj[ID(i / SZ, j / SZ + 1)].push_back(ID(i / SZ, j / SZ));
                        }
                }
}
void DFS(int v)
{
        MR[v] = 1;
        for (int u : Adj[v])
                if (!MR[u]) DFS(u);
}
int CountComps(int _sz = 10, int _df = 70, vector < int > _ignore = {0, 0, 0})
{
        SZ = _sz;
        DF = _df;
        IGNORE = _ignore;

        MakeGraph();
        int cp = 0;
        for (int i = 0; i < n; i += SZ)
                for (int j = 0; j < m; j += SZ)
                        if (!MR[ID(i / SZ, j / SZ)])
                                DFS(ID(i / SZ, j / SZ)), cp ++;

        memset(MR, 0, sizeof(MR));
        for (int i = 0; i < n; i += SZ)
                for (int j = 0; j < m; j += SZ)
                        Adj[ID(i / SZ, j / SZ)].clear();

        return cp;
}
double GreenShift(int _sz = 10, double leg = 0.0, double rig = 0.4)
{
        SZ = _sz;
        IGNORE = {0, 0, 0};

        int cnt = 1;
        double totg = 0;
        for (int i = 0; i < n; i += SZ)
                for (int j = 0; j < m; j += SZ)
                {
                        vector < int > X = GetMean(i, j);
                        double g = (double)X[1] / (double)(X[0] + X[1] + X[2]);
                        if (g >= leg && g <= rig)
                                continue;
                        totg += g; cnt ++;
                }
        totg /= (double)cnt;
        return totg;
}
double WhiteShift(int _sz = 10, int MXDF = 100, int GREY = 190)//double lew = 0.0, double riw = 0.4)
{
        SZ = _sz;
        IGNORE = {0, 0, 0};

        int cnt = 1, cnt2 = 1;
        for (int i = 0; i < n; i += SZ)
                for (int j = 0; j < m; j += SZ)
                {
                        vector < int > X = GetMean(i, j);
                        int mxdf = max({X[0], X[1], X[2]}) - min({X[0], X[1], X[2]});
                        if (mxdf > MXDF || max({X[0], X[1], X[2]}) <= GREY)
                                cnt ++;
                        else
                                cnt2 ++;
                }
        double rat = (double)cnt / (double)cnt2;
        return rat;
}
int Style()
{
        vector < double > Grad(5, 0);

        int cp1 = CountComps(7, 20, {1, 0, 1});

        if (cp1 <= 20) // Magnitude of 22,000
        {
                Grad[4] += exp((20 - cp1) / 2);
        }
        int cp2 = CountComps(7, 20, {0, 0, 1});
        if (cp2 <= 20) // Magnitude of 22,000
        {
                Grad[4] += exp((20 - cp2) / 2);
        }
        if (cp1 <= 20 && cp2 <= 20 && cp1 + cp2 <= 29)
                return 4;


        double gr = GreenShift(20, 0.0, 0.4);

        //cout << gr << endl;

        if (gr < 0.1)
                return 3;

        double wt = WhiteShift(5, 40, 130);

        gr = GreenShift(50, 0.0, 0.0);

//      cout << gr << endl;

//      cout << wt << endl;

        if (wt >= 3)
                return 2;

        return 1;
}
int style(int _n, int _m, int _R[500][500], int _G[500][500], int _B[500][500])
{
        n = _n; m = _m;
        for (int i = 0; i < n; i ++)
                for (int j = 0; j < m; j ++)
                        R[i][j] = _R[i][j], G[i][j] = _G[i][j], B[i][j] = _B[i][j];

        return Style();
}
#Verdict Execution timeMemoryGrader output
Fetching results...