「USACO2011 Nov Gold」解题报告

T1、Above the Median

$$Solution$$：

$r - (l - 1) \leq 2 \times (pre_r - pre_{l - 1})$

$r - 2 \times pre_r \leq (l - 1) - 2 \times pre_{l - 1}$

$$Source$$：

#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 1e5 + 5;

int n, nn, k, a[N], pre[N];
long long res;

struct binary_index_tree {
int a[N << 1];
void insert(int p) { for (; p <= nn; p += (p & -p)) ++a[p]; }
int ask(int p) { int ret = 0; for (; p; p -= (p & -p)) ret += a[p]; return ret; }
} bit;

int main() {
//freopen("in", "r", stdin);
n = in(), k = in(), nn = n + n;
for (int i = 1; i <= n; ++i)
a[i] = in();
for (int i = 1; i <= n; ++i)
pre[i] = pre[i - 1] + (a[i] >= k);
bit.insert(n);
for (int i = 1; i <= n; ++i) {
res += bit.ask(pre[i] + pre[i] - i + n);
bit.insert(pre[i] + pre[i] - i + n);
}
printf("%lld\n", res);
return 0;
}


T2、Binary Sudoku

$$Solution$$：

$$f_{k, i, x, y, z}$$ 表示到第 $$k$$ 行，其中 $$1$$$$k$$ 行每一列异或和的状态为 $$i$$ (一个二进制数)，当前的三个宫格异或和分别是 $$x,y,z$$ 的最少操作次数；

$$Source$$：

#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

int a[11][4], b[515][4], f[11][515][2][2][2];
char str[15];

int main() {
//freopen("in", "r", stdin);
for (int i = 1; i <= 9; ++i) {
scanf(" %s", str + 1);
for (int j = 1; j <= 9; ++j)
a[i][0] = (a[i][0] << 1) | (str[j] == '1');
for (int j = 0; j < 9; ++j)
a[i][j / 3 + 1] ^= (a[i][0] >> j) & 1;
}
for (int i = 1; i < 512; ++i) {
b[i][0] = b[i - (i & -i)][0] + 1;
for (int j = 0; j < 9; ++j)
b[i][j / 3 + 1] ^= (i >> j) & 1;
}
memset(f, 0x3f, sizeof(f));
f[0][0][0][0][0] = 0;
for (int k = 1, tmp, t1, t2, t3; k <= 9; ++k) {
if (k % 3 == 0) {
for (int i = 0; i < 512; ++i)
for (int j = 0; j < 512; ++j) {
if (b[j ^ a[k][0]][0] & 1)
continue;
t1 = a[k][1] ^ b[j][1];
t2 = a[k][2] ^ b[j][2];
t3 = a[k][3] ^ b[j][3];
tmp = f[k - 1][i ^ j ^ a[k][0]][t1][t2][t3];
chk_min(f[k][i][0][0][0], tmp + b[j][0]);
}
} else {
for (int i = 0; i < 512; ++i)
for (int x = 0; x < 2; ++x)
for (int y = 0; y < 2; ++y)
for (int z = 0; z < 2; ++z)
for (int j = 0; j < 512; ++j) {
if (b[j ^ a[k][0]][0] & 1)
continue;
t1 = x ^ a[k][1] ^ b[j][1];
t2 = y ^ a[k][2] ^ b[j][2];
t3 = z ^ a[k][3] ^ b[j][3];
tmp = f[k - 1][i ^ j ^ a[k][0]][t1][t2][t3];
chk_min(f[k][i][x][y][z], tmp + b[j][0]);
}
}
}
printf("%d\n", f[9][0][0][0][0]);
return 0;
}


T3、Cow Steeplechase

$$Source$$：

#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 255;

struct segment {
int x1, y1, x2, y2;
} a[N], b[N];
int n, x, y, mp[N][N], mat[N];

void prep() {
for (int i = 1; i <= x; ++i)
if (a[i].x1 > a[i].x2)
std::swap(a[i].x1, a[i].x2);
for (int i = 1; i <= y; ++i)
if (b[i].y1 > b[i].y2)
std::swap(b[i].y1, b[i].y2);
for (int i = 1; i <= x; ++i) {
for (int j = 1; j <= y; ++j) {
if (b[j].y1 <= a[i].y1 && a[i].y2 <= b[j].y2 &&
a[i].x1 <= b[j].x1 && b[j].x2 <= a[i].x2)
mp[i][j] = 1;
}
}
}

int vis[N];
int dfs(const int u, const int tim) {
if (vis[u] == tim)
return 0;
vis[u] = tim;
for (int v = 1; v <= y; ++v) {
if (!mp[u][v])
continue;
if (!mat[v] || dfs(mat[v], tim)) {
mat[v] = u;
return 1;
}
}
return 0;
}
int hungary() {
int ret = 0;
for (int i = 1; i <= x; ++i)
ret += dfs(i, i);
return ret;
}

int main() {
//freopen("in", "r", stdin);
n = in();
for (int i = 1; i <= n; ++i) {
a[++x] = (segment){in(), in(), in(), in()};
if (a[x].x1 == a[x].x2)
b[++y] = a[x--];
}
prep();
printf("%d\n", n - hungary());
return 0;
}

posted @ 2019-10-10 18:21  15owzLy1  阅读(111)  评论(0编辑  收藏  举报