Submission #955258

#TimeUsernameProblemLanguageResultExecution timeMemory
955258Programmer123Art Class (IOI13_artclass)C++17
65 / 100
96 ms15152 KiB
#ifndef ONLINE_JUDGE
#include "artclass.h"
#endif
#include <bits/stdc++.h>
struct pixel {
    double r, g, b;
    double h, s, l;
    pixel() {
        r = g = b = h = s = l = 0.0;
    }
    pixel(int _r, int _g, int _b) {
        r = _r / 255.0;
        g = _g / 255.0;
        b = _b / 255.0;
        auto xmax = std::max({r, g, b});
        auto xmin = std::min({r, g, b});
        auto c = xmax - xmin;
        l = (xmax + xmin) / 2;
        if (xmax == 0) {
            s = 0;
        } else {
            s = c / xmax;
        }
        if (c == 0.0) {
            h = 0;
        } else if (xmax == r) {
            h = 60.0 * (fmod(60.0 + ((g - b) / c), 6.0));
        } else if (xmax == g) {
            h = 60.0 * ((b - r) / c + 2.0);
        } else if (xmax == b) {
            h = 60.0 * ((r - g) / c + 4.0);
        } else {
            assert(false);
        }
    }
};
bool green(int r, int g, int b) {
    return (g > 100 && r < 100 && b < 100) || (g > 50 && r < 50 && b < 50);
}
double dist(pixel _a, pixel _b) {
    auto r = _a.r - _b.r;
    auto g = _a.g - _b.g;
    auto b = _a.b - _b.b;
    return std::sqrt(r * r + g * g + b * b);
}
double noise(std::vector<pixel> pixels) {
    double res = 0;
    for (int i = 0; i < pixels.size(); ++i) {
        for (int j = i + 1; j < pixels.size(); ++j) {
            res += dist(pixels[i], pixels[j]);
        }
    }
    return res;
}
int style(int H, int W, int R[500][500], int G[500][500], int B[500][500]) {
    std::mt19937 Rand(std::random_device{}());
    auto data = new pixel *[H];
    for (int i = 0; i < H; ++i) {
        data[i] = new pixel[W];
        for (int j = 0; j < W; ++j) {
            data[i][j] = pixel(R[i][j], G[i][j], B[i][j]);
        }
    }
    auto clean = [&]() {
        for (int i = 0; i < H; ++i) {
            delete[] data[i];
        }
        delete[] data;
    };
    std::vector<pixel> primaries = {
            {190, 10, 10},
            {238, 208, 3},
            {57, 96, 188},
            {240, 240, 240},
            {0, 0, 0},
            {174, 180, 194}};
    auto primary = [&](pixel x) {
        for (auto p: primaries) {
            if (dist(x, p) < 0.1) return true;
        }
        return false;
    };
    int numP = 0;
    for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            numP += primary(data[i][j]);
        }
    }
    if (numP > 40000) {
        clean();
        return 1;
    }
    //    return 0;
    int numG = 0;
    for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            numG += (dist(data[i][j], {108, 141, 71}) < 0.25) || (data[i][j].h > 75 && data[i][j].h < 150 && (data[i][j].l < 0.8) && (data[i][j].l > 0.2));
        }
    }
    const double BLUE_THRESHOLD = 0.25;
    int highB = 0, lowB = 0;
    for (int i = 0; i < H / 2; ++i) {
        for (int j = 0; j < W; ++j) {
            highB += (dist(data[i][j], {160, 180, 215}) < BLUE_THRESHOLD);
        }
    }
    for (int i = H / 2; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            lowB += (dist(data[i][j], {160, 180, 215}) < BLUE_THRESHOLD);
        }
    }
    std::map<int, int> diffs;
    for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            if (data[i][j].l < 0.2 || data[i][j].l > 0.8) continue;
            int num = std::floor(data[i][j].h / 10);
            diffs[num]++;
        }
    }
    int numlarge = 0;
    for (auto [a, b]: diffs) {
        //#ifdef LOCAL
        //        std::cout << "Colour " << a << ": " << b << std::endl;
        //#endif
        if (b > H * W / 4) numlarge++;
    }
    if (numG > 2000 && (highB > lowB * 1.5 || lowB < 50)) {
        clean();
        return 2;
    }
    int numW = 0;
    for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            if (data[i][j].l > 0.7) numW++;
        }
    }
    double Noise = 0.0;
    int rad = 10;
    for (int sample = 0; sample < 100; ++sample) {
        int r = Rand() % H;
        int c = Rand() % W;
        while (r - rad < 0 || r + rad >= H) {
            r = Rand() % H;
        }
        while (c - rad < 0 || c + rad >= W) {
            c = Rand() % W;
        }
        std::vector<pixel> pixels;
        for (int i = r - rad; i <= r + rad; ++i) {
            for (int j = c - rad; j <= c + rad; ++j) {
                pixels.push_back(data[i][j]);
            }
        }
        Noise += noise(pixels);
    }
    if (Noise >= 1000000) {
        clean();
        return 3;
    }
    clean();
    return 4;
}

#ifdef ONLINE_JUDGE
int _R[500][500];
int _G[500][500];
int _B[500][500];
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int T;
    std::cin >> T;
    for (int _ = 0; _ < T; ++_) {
        int H, W;
        std::cin >> H >> W;
        for (int i = 0; i < H; ++i) {
            for (int j = 0; j < W; ++j) {
                int a;
                std::cin >> a;
                _R[i][j] = (a >> 16) & 0xff;
                _G[i][j] = (a >> 8) & 0xff;
                _B[i][j] = a & 0xff;
            }
        }
        std::cout << style(H, W, _R, _G, _B) << std::endl;
    }
}
#endif

Compilation message (stderr)

artclass.cpp: In function 'double noise(std::vector<pixel>)':
artclass.cpp:48:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<pixel>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   48 |     for (int i = 0; i < pixels.size(); ++i) {
      |                     ~~^~~~~~~~~~~~~~~
artclass.cpp:49:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<pixel>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   49 |         for (int j = i + 1; j < pixels.size(); ++j) {
      |                             ~~^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...