답안 #758783

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
758783 2023-06-15T09:54:13 Z coloboxx 미술 수업 (IOI13_artclass) C++17
컴파일 오류
0 ms 0 KB
#include "artclass.h"

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define ll long long
#define point pair<int, int>
#define X first
#define Y second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define show(x) cerr << (#x) << " = " << x << '\n'
#define print(x) if (1) {cerr << (#x) << " = "; for (auto it : x) \
      cerr << it << ' '; cerr << '\n';}
#define fast_io ios_base::sync_with_stdio(0), cin.tie(0)

const int N = 512;
//const int S = 2e7 + 64;
const int INF = 2e9 + 64;
const ll MAX = 2e18 + 64;
const int LOG = 30;
const int MOD = 998244353;
const int P = 79;

using namespace std;
using namespace __gnu_pbds;

struct RGB {
      unsigned char r, g, b;
      RGB() {}
      RGB(unsigned char r, unsigned char g, unsigned char b) : r(r), g(g), b(b) {}

      unsigned char mx() {
            return max({r, g, b});
      }

      unsigned char mn() {
            return min({r, g, b});
      }
};

double dist(RGB e1, RGB e2) {
    long rmean = ( (long)e1.r + (long)e2.r ) / 2;
    long r = (long)e1.r - (long)e2.r;
    long g = (long)e1.g - (long)e2.g;
    long b = (long)e1.b - (long)e2.b;
    return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}

int sq(ll x) {
      return x * x;
}

// double dist(RGB e1, RGB e2) {
//       return sqrt(sq((int)e1.r - (int)e2.r) + sq((int)e1.g - (int)e2.g) + sq((int)e1.b - (int)e2.b));
// }

int a[N][N], used[N][N];

void clear() {
      for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                  a[i][j] = used[i][j] = 0;
}

int n, m, R[500][500], G[500][500], B[500][500];
RGB c[500][500];

const int dx[4] = {0, 0, -1, +1};
const int dy[4] = {-1, +1, 0, 0};

void select_by_diff(RGB color, double w, double f = 1e9) {
      clear();
      for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                  a[i][j] = dist(color, c[i][j]) <= w && c[i][j].mx() - c[i][j].mn() <= f;
}

RGB average(int x1, int y1, int x2, int y2) {
      ll sr = 0, sg = 0, sb = 0;
      for (int i = x1; i <= x2; ++i)
            for (int j = x1; j <= x2; ++j)
                  sr += c[i][j].r, sg += c[i][j].g, sb += c[i][j].b;

      int l = (y2 - y1 + 1) * (x2 - x1 + 1);
      return RGB(sr / l, sg / l, sb / l);
}

RGB average(vector<RGB> &v) {
      ll sr = 0, sg = 0, sb = 0;
      for (RGB color : v)
            sr += color.r, sg += color.g, sb += color.b;

      int l = v.size();
      return RGB(sr / l, sg / l, sb / l);
}

int cnt = 0;

// int dfs(int x, int y) {
//       ++cnt;
//       if (cnt % 33700 == 0)
//             show(x), show(y), show(cnt);

//       //show(used[0][0]);
//       assert(!used[x][y]);
//       assert(min(x, y) >= 0 && x < n && y < m);
//       used[x][y] = true;
//       int res = 1;
//       for (int k = 0; k < 4; ++k) {
//             int nx = x + dx[k];
//             int ny = y + dy[k];
//             if (min(nx, ny) >= 0 && nx < n && ny < m && !used[nx][ny] && a[nx][ny] == a[x][y])
//                   res += dfs(nx, ny);
//       }
//       return res;
// }

int bfs(int sx, int sy) {
      used[sx][sy] = true;
      queue<point> q;

      q.push({sx, sy});
      int res = 0;

      while (!q.empty()) {
            auto [x, y] = q.front();
            q.pop();

            ++res;
            used[x][y] = true;

            for (int dir = 0; dir < 4; ++dir) {
                  int nx = x + dx[dir];
                  int ny = y + dy[dir];

                  if (nx >= 0 && nx < n && ny >= 0 && ny < m && !used[nx][ny] && a[nx][ny] == a[x][y])
                        used[nx][ny] = true, q.push({nx, ny});
            } 
      }

      return res;
}

bool check_green(RGB color) {
      int r = color.r, g = color.g, b = color.b;

      return g - 8 >= max(r, b) || (g + 16 >= r && b <= min(r, g) * 4 / 5)
            || (min(g, r) >= 96 && b <= 48);
}

int bfs_green(int sx, int sy) {
      used[sx][sy] = true;
      queue<point> q;

      q.push({sx, sy});
      int res = 0;

      while (!q.empty()) {
            auto [x, y] = q.front();
            q.pop();

            ++res;
            used[x][y] = true;

            for (int dir = 0; dir < 4; ++dir) {
                  int nx = x + dx[dir];
                  int ny = y + dy[dir];

                  if (nx >= 0 && nx < n && ny >= 0 && ny < m && !used[nx][ny] && check_green(c[nx][ny]))
                        used[nx][ny] = true, q.push({nx, ny});
            } 
      }

      return res;
}


int count_components(int lim = 1) {
      for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                  used[i][j] = 0;

      int res = 0;
      for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                  if (!used[i][j])
                        res += (bfs(i, j) >= lim);

      return res;
}

const RGB GRAY = {20, 20, 20};
const RGB LGRAY = {235, 235, 235};

mt19937 rnd(time(0));

int count_bits() {
      int res = 0;
      for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                  res += a[i][j];
      return res;
}

int style(int R, int C, int r[500][500], int g[500][500], int b[500][500]) {
      // show(N), show(M);
      n = R, m = C;
      for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                  c[i][j] = RGB(r[i][j], g[i][j], b[i][j]);

      int cnt = 0, total = 0;
      for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j) {
                  for (int k = 0; k < 4; ++k) {
                        int ni = i + dx[k], nj = j + dy[k];
                        if (ni >= 0 && nj >= 0 && ni < n && nj < m) {
                              ++total;
                              cnt += dist(c[i][j], c[ni][nj]) <= 16.0;
                        }
                  }
            }

      assert(total != 0);

      double coeff = (double)cnt / (double)total;
      // show(coeff);

      if (coeff >= 0.45) {
            select_by_diff(GRAY, 128.0, 24.0);
            int c1 = count_components(750);
            int b1 = count_bits();

            select_by_diff(LGRAY, 72.0, 16.0);
            int c2 = count_components(750);
            int b2 = count_bits();

            // show(c1), show(c2);
            // show(b1), show(b2);

            if (max(c1, c2) >= 8)
                  return 1;
            else
                  return 4;
      }
      else {
            if (coeff < 0.1)
                  return 3;
            if (coeff > 0.3)
                  return 2;

            vector<point> v;

            for (int i = 0; i < n; ++i)
                  for (int j = 0; j < m; ++j)
                        if (check_green(c[i][j]))
                              v.pb({i, j});

            int cnt_green = 0;
            clear();

            // show(v.size());

            if (v.size() < 2000)
                  return 3;

            for (int t = 0; t < 400; ++t) {
                  auto [x, y] = v[rnd() % v.size()];

                  if (used[x][y]) {
                        --t; continue;
                  }

                  double coeff_green = (double)bfs_green(x, y) / (double)(n * m);
                  if (coeff_green >= 0.12)
                        return 2;

                  cnt_green += coeff_green >= 0.02;
                  // show(coeff_green);
            }

            // show(cnt_green);     

            // show(count_components(1000));

            return (cnt_green >= 5 || count_bits() >= n * m * 15 / 100 ? 2 : 3);
}

// signed main() {
//       string folder = "C:\\Users\\nazar\\Desktop\\Sublime\\ArtClass\\files\\";

//       for (int type = 1; type <= 4; ++type) {
//             cerr << "------- TYPE #" << type << ": -------\n";
//             for (int sample = 1; sample <= 9; ++sample) {
//                   cerr << "\n\n";
//                   cerr << "sample #" << sample << ": \n";
//                   string path = folder + "sample" + to_string(type) + "-0" + to_string(sample);
//                   //show(path);
//                   ifstream file(path.c_str());

//                   int n, m;
//                   file >> n >> m;

//                   for (int i = 0; i < n; ++i)
//                         for (int j = 0; j < m; ++j)
//                               file >> R[i][j] >> G[i][j] >> B[i][j];

//                   cout << style(n, m, R, G, B) << '\n' << '\n';
//                   file.close();
//             }
//       }
// }

Compilation message

artclass.cpp: In function 'int style(int, int, int (*)[500], int (*)[500], int (*)[500])':
artclass.cpp:233:17: warning: unused variable 'b1' [-Wunused-variable]
  233 |             int b1 = count_bits();
      |                 ^~
artclass.cpp:237:17: warning: unused variable 'b2' [-Wunused-variable]
  237 |             int b2 = count_bits();
      |                 ^~
artclass.cpp:288:1: error: expected '}' at end of input
  288 | }
      | ^
artclass.cpp:206:76: note: to match this '{'
  206 | int style(int R, int C, int r[500][500], int g[500][500], int b[500][500]) {
      |                                                                            ^