连接奶牛(春季每日一题 56)
原创
©著作权归作者所有:来自51CTO博客作者sweetheart7_7的原创作品,请联系作者获取转载授权,否则将追究法律责任
每天农夫约翰都会去巡视农场,检查他的
每头奶牛的位置由二维平面中的一个点描述,而约翰从原点
所有奶牛的位置互不相同,且都不在原点。
为了使自己的路线更有趣,农夫约翰决定只沿平行于坐标轴的方向行走,即只能向北,向南,向东或向西行走。
此外,他只有在到达奶牛的位置时才能改变行进方向(如果需要,他也可以选择通过奶牛的位置而不改变方向)。
在他改变方向时,可以选择转向 或
约翰的行进路线必须满足在他访问完所有奶牛后能够回到原点。
如果他在每头奶牛的位置处恰好转向一次,请计算出约翰访问他的
允许他在不改变方向的情况下通过任意奶牛的位置任意次数。
同一几何路线正向走和反向走算作两条不同的路线。
输入格式
第一行包含整数 。
接下来 行,每行包含两个整数
输出格式
输出不同路线的数量。
如果不存在有效路线,则输出 。
数据范围
,
输入样例:
输出样例:
样例解释
共有两条不同路线 和 。
全排列枚举顺序,然后对每种排列进行判断,当从一个到另一个点时,必须有 坐标 或者
#include<iostream>
#define x first
#define y second
using namespace std;
const int N = 15;
typedef pair<int, int> PII;
int n, res;
int a[N];
PII q[N];
bool st[N];
bool check(){
int x = 0, y = 0;
int dx, dy, rdx = -10, rdy = -10;
for(int i = 0; i <= n; i++){
int idx = a[i];
if(q[idx].x != x && q[idx].y != y) return false;
if(q[idx].x == x) dx = 0, dy = (q[idx].y - y) / abs(q[idx].y - y);
if(q[idx].y == y) dy = 0, dx = (q[idx].x - x) / abs(q[idx].x - x);
if(dx == rdx && dy == rdy) return false;
rdx = dx, rdy = dy;
x = q[idx].x, y = q[idx].y;
}
return x == 0 && y == 0;
}
void dfs(int cnt){
if(cnt == n){
if(check()) res++;
return;
}
for(int i = 0; i < n; i++){
if(st[i]) continue;
st[i] = true;
a[cnt] = i;
dfs(cnt + 1);
a[cnt] = -1;
st[i] = false;
}
}
int main(){
cin >> n;
for(int i = 0; i < n; i++)
cin >> q[i].x >> q[i].y;
q[n].x = 0, q[n].y = 0;
a[n] = n;
dfs(0);
cout << res << endl;
return 0;
}