题意:平面内有N头牛$N\le 10$john从(0,0)出发,最后回到(0,0)
只有走到牛那里john才可以改变方向,否则沿着直线走
问john经过每一头牛并且在每一头牛出恰好改变方向一次的方案(牛可以经过多次,但只能改变方向一次)
(dfs没写出来)
看到$n\le 10$就容易多了
用next_permutation枚举改变方向的牛的顺序
判断是否成立即可
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define olinr return #define _ 0 #define love_nmr 0 #define DB double inline int read() {int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; } inline void put(int x) {if(x<0){x=-x;putchar('-');}if(x>9)put(x/10);putchar(x%10+'0'); } int n; int ans; int a[15]; struct node {int x;int y; }cow[15]; bool pd[15]; inline bool doit() {int lx=0; //上头牛int ly=0;for(int i=0;i<n;i++){int x=cow[a[i]].x; //当前牛int y=cow[a[i]].y;int nx=cow[a[i+1]].x; //下头牛int ny=cow[a[i+1]].y;if(x!=lx&&y!=ly) return false; //无法到达if(x!=nx&&y!=ny) return false;int xx=x-lx;int yy=y-ly;int xxx=nx-x;int yyy=ny-y;if(xx*xxx+yy*yyy>0) return false; //没拐弯(向量点乘判断)lx=x; ly=y;}return true; } int main() {n=read();for(int i=0;i<=n;i++)a[i]=i;for(int i=0;i<n;i++){cow[i].x=read();cow[i].y=read();}do{ans+=doit();}while(next_permutation(a,a+n));put(ans);olinr ~~(0^_^0)+love_nmr; }
感谢rqj dalao对蒟蒻的指点