ICPC NERC 2022-2023 做题笔记 / 代码集
ICPC NERC 2022-2023 做题笔记 / 代码集
目录
A - Amazing Trick
ケロシの代码
const int N = 1e5 + 5;
mt19937 rnd(time(0));
int n, a[N], p[N], q[N], p1[N], p2[N];
void solve() {
cin >> n;
FOR(i, 1, n) cin >> a[i];
FOR(i, 1, n) p[i] = i;
bool ok = 0;
REP(_, 200) {
shuffle(p + 1, p + n + 1, rnd);
bool fl = 1;
FOR(i, 1, n) fl &= p[i] != i && p[i] != a[i];
ok |= fl;
if(ok) break;
}
if(! ok) {
cout << "Impossible" << endl;
return;
}
cout << "Possible" << endl;
FOR(i, 1, n) q[a[i]] = i;
FOR(i, 1, n) p1[i] = q[p[i]];
FOR(i, 1, n) q[a[p1[i]]] = i;
FOR(i, 1, n) p2[i] = q[i];
FOR(i, 1, n) cout << p1[i] << " "; cout << endl;
FOR(i, 1, n) cout << p2[i] << " "; cout << endl;
}
D - Dominoes
ケロシの代码
const int N = 2e3 + 5;
const int M = 1e5 + 5;
const int V = 1e6;
const int INF = 0x3f3f3f3f;
int n, m;
string s[N];
int a[N][N], cnt;
int dx[] = {0, 0, 1, - 1};
int dy[] = {1, - 1, 0, 0};
struct Edge { int ne, to, ew; } e[M];
int fi[N], c[N], ecnt;
int S, T, d[N];
int vis[N];
void init() {
ecnt = 1;
memset(fi, 0, sizeof fi);
}
void add(int u, int v, int w) {
e[++ ecnt] = {fi[u], v, w};
fi[u] = ecnt;
e[++ ecnt] = {fi[v], u, 0};
fi[v] = ecnt;
}
bool bfs() {
memset(d, 0x3f, sizeof d);
queue<int> q;
d[S] = 0; q.push(S);
while(! q.empty()) {
int u = q.front();
q.pop();
for(int i = fi[u]; i; i = e[i].ne) if(e[i].ew) {
int v = e[i].to;
if(d[v] == INF) {
d[v] = d[u] + 1;
q.push(v);
}
}
}
return d[T] != INF;
}
int dfs(int u, int w) {
if(u == T || ! w) return w;
int res = 0;
for(int & i = c[u]; i; i = e[i].ne) if(e[i].ew) {
int v = e[i].to;
if(d[v] != d[u] + 1) continue;
int val = dfs(v, min(w, e[i].ew));
if(! val) continue;
e[i].ew -= val;
e[i ^ 1].ew += val;
w -= val;
res += val;
if(! w) return res;
}
return res;
}
int dinic(int _S, int _T) {
S = _S, T = _T;
int res = 0;
while(bfs()) {
memcpy(c, fi, sizeof c);
res += dfs(S, INF);
}
return res;
}
void solve() {
cin >> n >> m;
FOR(i, 1, n) {
cin >> s[i];
s[i] = ' ' + s[i];
}
FOR(i, 1, n) FOR(j, 1, m) if(s[i][j] == '.') if((i + j) & 1)
a[i][j] = ++ cnt;
FOR(i, 1, n) FOR(j, 1, m) if(s[i][j] == '.') if(! ((i + j) & 1))
a[i][j] = ++ cnt;
cnt /= 2;
if(1ll * cnt * (cnt - 1) >= V) {
cout << V << endl;
return;
}
int S = 0, T = cnt * 2 + 1;
init();
FOR(i, 1, cnt) add(S, i, 1);
FOR(i, 1, cnt) add(i + cnt, T, 1);
FOR(i, 1, n) FOR(j, 1, m) if(s[i][j] == '.') if((i + j) & 1) REP(d, 4) {
int x = i + dx[d], y = j + dy[d];
if(x < 1 || x > n || y < 1 || y > m) continue;
if(s[x][y] == '#') continue;
add(a[i][j], a[x][y], 1);
}
dinic(S, T);
int ans = cnt * (cnt - 1);
FOR(i, 1, cnt) {
FOR(j, 1, cnt * 2) vis[j] = 0;
queue<int> q;
q.push(i); vis[i] = 1;
while(! q.empty()) {
int u = q.front();
q.pop();
for(int i = fi[u]; i; i = e[i].ne) if(e[i ^ 1].ew) {
int v = e[i].to;
if(v == S || v == T) continue;
if(! vis[v]) {
vis[v] = 1;
q.push(v);
}
}
}
FOR(j, cnt + 1, cnt * 2) ans += ! vis[j];
}
chmin(ans, V);
cout << ans << endl;
}
G - Game of Questions
ケロシの代码
const int N = 17;
int n, m, a[1 << N], b[1 << N], c[1 << N];
double f[1 << N];
void solve() {
cin >> n >> m;
REP(_, n) {
string s; cin >> s;
int S = 0;
REP(i, m) if(s[i] == '1') S |= 1 << i;
a[S] ++;
}
int U = (1 << m) - 1;
REP(S, 1 << m) b[S] = a[S];
REP(i, m) ROF(S, U, 1) if(S >> i & 1) b[S ^ (1 << i)] += b[S];
f[U] = 1;
double ans = 0;
ROF(S, U, 1) if(S & 1) {
int s = n;
int W = S ^ U;
for(int T = W; T != - 1; T = T ? (W & (T - 1)) : - 1)
s -= a[T] + a[T ^ S];
if(s == 0) {
ans += f[S];
}
else {
vector<int> e;
for(int T = S; T; T = S & (T - 1)) {
c[T] = b[T];
e.push_back(T);
}
REP(i, m) if(S >> i & 1) ROF(j, SZ(e) - 1, 1) {
int T = e[j];
if(! (T >> i & 1)) c[T] -= c[T ^ (1 << i)];
}
ROF(j, SZ(e) - 1, 1) {
int T = e[j];
f[T] += f[S] * c[T] / s;
}
}
}
cout << fixed << setprecision(12);
cout << ans << endl;
}
I - Interactive Factorial Guessing
ケロシの代码
const int N = 6e3 + 5;
const int M = 2e4;
const int INF = 1e9 + 7;
int n, a[N][M], c[10];
int d[] = {181, 1483, 1692, 2017, 1543, 1524, 1467, 1786, 1456, 1600};
void init() {
n = 5982;
a[0][0] = 1;
FOR(i, 1, n) {
REP(j, M) a[i][j] = a[i - 1][j];
REP(j, M) a[i][j] *= i;
REP(j, M) if(a[i][j] > 9) {
a[i][j + 1] += a[i][j] / 10;
a[i][j] %= 10;
}
}
}
int query(int u) {
cout << "? " << u << endl << flush;
int x; cin >> x;
return x;
}
void solve() {
vector<int> p;
FOR(i, 1, n) p.push_back(i);
int u = 1601;
int y = query(u);
vector<int> q;
for(int x : p) if(a[x][u] == y) q.push_back(x);
p = q;
u = d[y];
y = query(u);
q.clear();
for(int x : p) if(a[x][u] == y) q.push_back(x);
p = q;
while(SZ(p) > 1) {
int u = 0, val = INF;
REP(j, M) {
REP(i, 10) c[i] = 0;
for(int x : p) {
c[a[x][j]] ++;
if(c[a[x][j]] == val) break;
}
int res = 0;
REP(i, 10) chmax(res, c[i]);
if(chmin(val, res)) u = j;
}
int y = query(u);
vector<int> q;
for(int x : p) if(a[x][u] == y) q.push_back(x);
p = q;
}
cout << "! " << p[0] << endl << flush;
string s; cin >> s;
}