1 条题解

  • 0
    @ 2026-8-29 23:08:09
    #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
    上传者