题目请点我
题解:
这道题思路很简单,就是简单的深搜,找出所有的组合,然后判断能否成环。关键在于如何判断能否成环,我的思路是利用递归模拟,看能否第二次经过某一个点。中间也出现了错误,首先,每次访问的下一个点应该是同一行上当前点右边的第一个点;其次,某个点被访问过必须是作为起点被访问过,而不仅仅是到达。
代码实现:
/*
ID: eashion
LANG: C++
TASK: wormhole
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAX 13
#define INF 0x7fffffff
using namespace std;
struct node{
int x,y;
};
int N;
int res;
int used[MAX];
//配对信息
int Pair[MAX];
//点集
node Nlis[MAX];
//测试是否成环
bool test();
//debug打印输出结果
void print();
void dfs(int pos);
//递归
bool if_sucked(int pos);
int main()
{
freopen("wormhole.in","r",stdin);
freopen("wormhole.out","w",stdout);
while( scanf("%d",&N) != EOF ){
res = 0;
memset(used,0,sizeof(used));
memset(Pair,-1,sizeof(Pair));
for( int i = 0; i < N; i++ ){
scanf("%d%d",&Nlis[i].x,&Nlis[i].y);
}
dfs(0);
printf("%d\n",res);
}
return 0;
}
void dfs( int pos ){
if( pos == N ){
if( test() ){
res++;
//print();
//快速debug,定位到合理解再进行一次测试
//test();
}
return ;
}
if( Pair[pos] == -1 ){
for( int i = pos+1; i < N; i++ ){
if( Pair[i] == -1 ){
Pair[i] = pos;
Pair[pos] = i;
dfs(pos+1);
Pair[i] = -1;
Pair[pos] = -1;
}
}
}
else{
dfs(pos+1);
}
return ;
}
bool test(){
for( int i = 0; i < N; i++ ){
memset(used,0,sizeof(used));
if( if_sucked(i) ){
return true;
}
}
return false;
}
bool if_sucked(int pos){
bool flag = false;
//这里仅标记每一次的起点被访问过
used[pos] = 1;
//used[Pair[pos]] = 1;
int x = Nlis[Pair[pos]].x;
int y = Nlis[Pair[pos]].y;
int dis = INF;
int in = -1;
//找到右边第一个点
for( int i = 0; i < N; i++ ){
if( Nlis[i].x > x && Nlis[i].y == y ){
if( Nlis[i].x-x < dis ){
dis = Nlis[i].x-x;
in = i;
}
}
}
if( in != -1 ){
if( used[in] == 1 ){
flag = true;
}
else{
flag = if_sucked(in);
}
}
return flag;
}
void print(){
for( int i = 0; i < N; i++ ){
printf("%d %d\n",i,Pair[i]);
}
printf("\n");
}
还有例程上的解法,很巧妙,类似于并查集的感觉。
#include <iostream>
#include <fstream>
using namespace std;
#define MAX_N 12
int N, X[MAX_N+1], Y[MAX_N+1];
int partner[MAX_N+1];
int next_on_right[MAX_N+1];
bool cycle_exists(void)
{
for (int start=1; start<=N; start++) {
// does there exist a cylce starting from start
int pos = start;
for (int count=0; count<N; count++)
pos = next_on_right[partner[pos]];
if (pos != 0) return true;
}
return false;
}
// count all solutions
int solve(void)
{
// find first unpaired wormhole
int i, total=0;
for (i=1; i<=N; i++)
if (partner[i] == 0) break;
// everyone paired?
if (i > N) {
if (cycle_exists()) return 1;
else return 0;
}
// try pairing i with all possible other wormholes j
for (int j=i+1; j<=N; j++)
if (partner[j] == 0) {
// try pairing i & j, let recursion continue to
// generate the rest of the solution
partner[i] = j;
partner[j] = i;
total += solve();
partner[i] = partner[j] = 0;
}
return total;
}
int main(void)
{
ifstream fin("wormhole.in");
fin >> N;
for (int i=1; i<=N; i++) fin >> X[i] >> Y[i];
fin.close();
for (int i=1; i<=N; i++) // set next_on_right[i]...
for (int j=1; j<=N; j++)
if (X[j] > X[i] && Y[i] == Y[j]) // j right of i...
if (next_on_right[i] == 0 ||
X[j]-X[i] < X[next_on_right[i]]-X[i])
next_on_right[i] = j;
ofstream fout("wormhole.out");
fout << solve() << "\n";
fout.close();
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/eashion1994/article/details/46944933