有个数据能在我机子上跑对,在服务器上过不去,卡了我很久。后来才发现,有个数组大小少开了一个。
题意是,有头牛只会沿着x轴正方向走,但是y坐标随机。图上有很多虫洞,两两相连,从一个虫洞进去,从对应虫洞出来之后,牛还是会沿着x轴正方向走,让你统计虫洞两两相连的方式,其中会导致牛陷入循环的个数。
关于排列组合,两两相配的个数什么的还好,但是如何生成配对,编程什么的一开始我还真不会。以前也就自己写过全排列或者组合而已,没有写过这种。
/* ID: modengd1 PROG: wormhole LANG: C++ */ #include <iostream> #include <stdio.h> #include <memory.h> using namespace std; int x[13],y[13]; int rightIndex[13]; int paired[13]; int N; bool cycle_exists() { bool vis[13]; //枚举从不同的点的左边进入 for(int start=1;start<=N;start++) { int now=start; memset(vis,false,sizeof(vis)); vis[now]=true; while(true) { //出 now=paired[now]; if(rightIndex[now]==0) break; //检查要进的口是否进过了 if(vis[rightIndex[now]]) return true; //从右面临近的虫洞进去 now=rightIndex[now]; vis[now]=true; } } return false; } int slove() { int a=-1,ans=0; for(int i=1;i<=N;i++) { if(paired[i]==0) { a=i; break; } } if(a==-1) { if(cycle_exists()) return 1; else return 0; } for(int i=a+1;i<=N;i++) { if(paired[i]==0) { paired[i]=a; paired[a]=i; ans+=slove(); paired[i]=paired[a]=0; } } return ans; } int main() { freopen("wormhole.in","r",stdin); freopen("wormhole.out","w",stdout); scanf("%d",&N); for(int i=1;i<=N;i++) { scanf("%d%d",&x[i],&y[i]); } memset(paired,0,sizeof(paired)); memset(rightIndex,0,sizeof(rightIndex)); //找到各个节点最近的右相邻 for(int i=1;i<=N;i++) { for(int j=1;j<=N;j++) { if(y[i]==y[j]&&x[i]<x[j]) { if(rightIndex[i]==0||x[j]<x[rightIndex[i]]) rightIndex[i]=j; } } } cout<<slove()<<endl; return 0; }
时间: 2024-12-13 16:28:36