# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
280336 | Kastanda | 미술 수업 (IOI13_artclass) | C++11 | 103 ms | 12848 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
// 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 <= 30) // Magnitude of 22,000
{
Grad[3] = -1e9;
Grad[4] += exp((30 - cp1) / 2);
}
int cp2 = CountComps(7, 20, {0, 0, 1});
if (cp2 <= 30) // Magnitude of 22,000
{
Grad[3] = -1e9;
Grad[4] += exp((30 - cp2) / 2);
}
if (cp1 >= 30 && cp2 >= 30)
Grad[4] = -1e9;
//cout << cp1 << " :: " << cp2 << endl;
//if (cp1 <= 20 && cp2 <= 20 && cp1 + cp2 <= 29)
//return 4;
int cp = CountComps(7, 10, {0, 1, 1});
if (cp >= 100)
Grad[4] = -1e9;
double gr = GreenShift(20, 0.0, 0.4);
if (gr < 0.2)
{
Grad[3] += exp((20 - gr * 100) / 2);
Grad[4] += exp((20 - gr * 100) / 3);
//return 3;
}
if (gr > 0.3)
{
Grad[1] += exp(((gr - 0.3) * 100) / 2);
Grad[2] += exp(((gr - 0.3) * 100) / 2);
}
double wt = WhiteShift(5, 40, 130);
if (wt < 3.0)
{
Grad[4] = -1e9;
Grad[3] += exp((20 - wt * 20.0/3.0) / 2);
Grad[1] += exp((20 - wt * 20.0/3.0) / 2);
}
/*for (int i = 1; i <= 4; i ++)
cout << Grad[i] << " : ";
cout << endl;*/
double Mx = -1e18;
for (int i = 1; i <= 4; i ++)
Mx = max(Mx, Grad[i]);
if (Mx == Grad[3])
return 3;
if (Mx == Grad[4])
return 4;
gr = GreenShift(20, 0.2, 0.4);
// cout << gr << endl;
// cout << wt << endl;
// if (wt >= 3)
// return 2;
if (Grad[1] > Grad[2])
return 1;
return 2;
}
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 time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |