搬运自己的博客,原载于 cyz14.farbox.com 2016-07-01自己的博客。
——以下为原文——
还是高二或者高三的时候开始做USACO的题,结果做了几题就做不下去了,被挡在了Wormholes这题。在家无事,今天又想起了,于是花了点时间做了出来。
做完后对照标程感慨自己还是搞的太复杂了。
我是想首先要把坐标离散化,映射到一个小范围内,然后递归找出所有配对方案,再在地图上模拟找循环。
”’
/*
ID: chenyaz1
PROG: wormhole
LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 12 + 1;
struct hole
{
int x, y;
} holes[MAXN];
int N;
int farm[MAXN][MAXN];
int max_x, max_y;
int my_pair[MAXN];
int ans = 0;
bool compareXFirst(hole a, hole b)
{
if (a.x < b.x) return true;
if (a.x > b.x) return false;
if (a.y < b.y) return true;
if (a.y > b.y) return false;
return false;
}
bool compareYFirst(hole a, hole b)
{
if (a.y < b.y) return true;
if (a.y > b.y) return false;
if (a.x < b.x) return true;
if (a.x > b.x) return false;
return false;
}
void init()
{
cin >> N;
for (int i = 1; i <= N; ++i)
cin >> holes[i].x >> holes[i].y;
sort(holes + 1, holes + N + 1, compareYFirst);
int cury = -1;
int disy = -1;
for (int i = 1; i <= N; ++i) {
if (holes[i].y != cury) {
cury = holes[i].y;
holes[i].y = ++disy;
} else {
holes[i].y = disy;
}
}
max_y = disy;
// for (int i = 1; i <= N; ++i)
// cout << holes[i].x << ' ' << holes[i].y << endl;
sort(holes + 1, holes + N + 1, compareXFirst);
int curx = -1;
int disx = -1;
for (int i = 1; i <= N; ++i) {
if (holes[i].x != curx) {
curx = holes[i].x;
holes[i].x = ++disx;
} else {
holes[i].x = disx;
}
}
max_x = disx;
// for (int i = 1; i <= N; ++i)
// cout << holes[i].x << ' ' << holes[i].y << endl;
memset(farm, 0, sizeof(farm));
for (int i = 1; i <= N; ++i)
farm[holes[i].x][holes[i].y] = i;
// for (int i = 0; i < MAXN; ++i)
// {
// for (int j = 0; j < MAXN; ++j)
// {
// cout << farm[i][j];
// }
// cout << endl;
// }
// cout << max_x << endl << max_y << endl;
}
void print_ans() {
for (int i = 1; i <= N; i++)
printf("%3d ", i);
cout << endl;
for (int i = 1; i <= N; i++)
printf("%3d ", my_pair[i]);
cout << endl;
for (int i = 0; i <= max_x; ++i)
{
for (int j = 0; j <= max_y; ++j)
{
cout << farm[i][j];
}
cout << endl;
}
}
void check() {
int passedIn[MAXN];
int passedOut[MAXN];
for (int i = 1; i <= N; i++) passedIn[i] = passedOut[i] = 0;
hole cur;
cur.x = cur.y = -1;
for (int i = 1; i <= N; i++) {
if (!passedIn[i]) {
cur = holes[i];
passedIn[i]++;
cur = holes[my_pair[i]];
passedIn[my_pair[i]]++;
while (1) {
cur.x += 1;
if (cur.x >= MAXN) break;
int tmp = farm[cur.x][cur.y];
if (tmp != 0) {
if (passedIn[tmp] > MAXN) {
ans++;
#ifdef __LOCAL__
cout << "pass In" << endl;
print_ans();
#endif
return;
} else {
passedIn[tmp]++;
cur = holes[my_pair[tmp]];
passedIn[my_pair[tmp]]++;
}
}
}
for (int i = 1; i <= N; i++) passedIn[i] = 0;
}
if (!passedOut[i]) {
cur = holes[i];
passedOut[i]++;
while (1) {
cur.x += 1;
if (cur.x >= MAXN) break;
int tmp = farm[cur.x][cur.y];
if (tmp != 0) {
if (passedOut[tmp] > MAXN) {
ans++;
#ifdef __LOCAL__
cout << "Pass out" << endl;
print_ans();
#endif
return;
} else {
passedOut[tmp]++;
cur = holes[my_pair[tmp]];
passedOut[my_pair[tmp]]++;
}
}
}
for (int i = 1; i <= N; i++) passedOut[i] = 0;
}
}
memset(farm, 0, sizeof(farm));
for (int i = 1; i <= N; ++i)
farm[holes[i].x][holes[i].y] = i;
}
void find_pair(int cur, bool* now) {
bool vis[MAXN];
for (int i = 0; i <= N; i++) vis[i] = now[i];
for (int i = 1; i <= N; i++) {
if (i > cur && !vis[i]) {
my_pair[cur] = i;
my_pair[i] = cur;
vis[i] = vis[cur] = true;
bool all_paired = true;
int to_pair = -1;
for (int j = 1; j <= N; j++) if (!vis[j]) {
all_paired = false;
to_pair = j;
break;
}
if (all_paired) {
check();
vis[i] = vis[cur] = false;
my_pair[i] = my_pair[cur] = 0;
return;
} else {
find_pair(to_pair, vis);
}
vis[i] = vis[cur] = false;
my_pair[i] = my_pair[cur] = 0;
}
}
}
void work()
{
bool vis[MAXN];
for (int i = 1; i <= N; ++i) vis[i] = false;
find_pair(1, vis);
}
int main()
{
freopen("wormhole.in", "r", stdin);
freopen("wormhole.out", "w", stdout);
init();
work();
cout << ans << endl;
return 0;
}
'''
写得丑,懒得改。