1 条题解
-
0
#include<iostream> #include<cstring> using namespace std; /* 算法步骤: ①搜索所有可能的配对,需要确保不会重复: -> n 个不同的物品放到 n/2 个相同的盒子里,不能出现重复。 -> 每对中的第 2 个元素 > 第 1 个元素,第 i 对的第 1 个元素 > 第 i-1 对的第 1 个元素 ②判断是否会出现循环: -> 对于每一种配对方案,依次模拟 Bessie 从第 1 个到第 n 个虫洞出发。 -> 模拟走 n 步,根据抽屉原理,如果 n 步以后 Bessie 还在某个虫洞中则, 出现了循环。 ③初始化: -> 记录每个虫洞右边的虫洞,模拟判断循环时使用。 */ const int N=15; struct Node{ int x,y;//虫洞的 x 和 y 坐标 }w[N]; //part[i]存储第 i 个虫洞的配对虫洞,to[i]记录 i 右边的虫洞。 int n,ans,part[N],to[N]; bool is_cycle(){ //模拟从第 1 个到第 n 个虫洞出发 for(int start=1;start<=n;start++){ int pos=start; for(int cnt=1;cnt<=n;cnt++) pos=to[part[pos]]; if(pos) return true; } return false; } //n 个不同的物品放到 n/2 个相同的盒子里,不能出现重复。 //为防止重复,搜索过程中没对中的元素 2>元素 1,每一对的元素 1>上一对的元素 1 。 void dfs(int cur,int pre){ if(cur>n/2){ if(is_cycle())//所有配对完成,到达目的地 ans++; return; } for(int i=pre+1;i<=n;i++) if(!part[i])//i 还未配对 for(int j=i+1;j<=n;j++) if(!part[j]){//j 还未配对 part[i]=j,part[j]=i;//i 和 j 配对 dfs(cur+1,i); part[i]=part[j]=0; //i 和 j 始终在变动,需要恢复状态 } } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>w[i].x>>w[i].y; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(w[j].y==w[i].y&&w[j].x>w[i].x) if(to[i]==0||w[j].x<w[to[i]].x) to[i]=j;//j 在 i 右边 dfs(1,0); cout<<ans; return 0; }
- 1
信息
- ID
- 993
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 8
- 标签
- 递交数
- 12
- 已通过
- 8
- 上传者