# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
758784 | coloboxx | 미술 수업 (IOI13_artclass) | C++17 | 85 ms | 7332 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 <= 56);
}
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 = {230, 230, 230};
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, 135.0, 30.0);
int c1 = count_components(550);
int b1 = count_bits();
select_by_diff(LGRAY, 80.0, 25.0);
int c2 = count_components(550);
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();
// }
// }
// }
컴파일 시 표준 에러 (stderr) 메시지
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |