题意是给若干多米若骨牌,每张牌两侧有数字,两张牌在面对面数字相同的情况下可以放在一起,求一中摆放方式..把每张牌看成一条边,连接这张牌牌两侧的数字表示的节点..这样就是一个球欧拉通路的问题了...另外注意判断一下无解,还有搜完欧拉通路后,判断一下是不是所有的边都用上了,否则就是存在不连通的情况..
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
struct node
{
int adv,num;
node()
{
}
node(int p,int q)
{
adv=p;
num=q;
}
};
vector <node>ans;
vector <node> g[10];
vector <int>a[10][10];
int cnt[10][10];
int n,m,p,q;
int tot;
bool vis[300];
void euler(int u)
{
for (int j=0; j<g[u].size(); j++)
{
int v=g[u][j].adv;
if (!vis[g[u][j].num])
{
vis[g[u][j].num]=true;
euler(v);
// cout<<u<<" "<<v<<endl;
ans.push_back(node(u,v));
}
}
}
int deg[10];
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&n);
memset(cnt,0,sizeof cnt);
memset(vis,false,sizeof vis);
memset(deg,0,sizeof deg);
tot=0;
for (int i=1; i<=n; i++)
{
scanf("%d%d",&p,&q);
deg[p]++;
deg[q]++;
a[p][q].push_back(i);
g[p].push_back(node(q,tot));
g[q].push_back(node(p,tot++));
}
int sum=0;
int st;
for (int i=0; i<7; i++)
if (deg[i]&1)
{
sum++;
st=i;
}
if (sum==0)
{
for (int i=0; i<7; i++)
if (deg[i]!=0)
{
st=i;
break;
}
}
else
if (sum>2)
{
puts("No solution");
return 0;
}
euler(st);
sum=0;
for (int i=0; i<tot; i++)
if (!vis[i])
{
puts("No solution");
return 0;
}
memset(vis,0,sizeof vis);
for (int i=ans.size()-1; i>=0; i--)
{
p=ans[i].adv;
q=ans[i].num;
bool ft=false;
for (int i=0; i<a[p][q].size(); i++)
if (!vis[a[p][q][i]])
{
printf("%d +\n",a[p][q][i]);
vis[a[p][q][i]]=true;
ft=true;
break;
}
if (ft) continue;
for (int i=0; i<a[q][p].size(); i++)
{
if (!vis[a[q][p][i]])
{
printf("%d -\n",a[q][p][i]);
vis[a[q][p][i]]=true;
ft=true;
break;
}
}
}
return 0;
}