101. Domino
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
题解:
求多米诺骨牌按照一定方式放置能否使相邻的位置数字相同。其实就是求无向图的欧拉通路,dfs即可。
但需要注意以下几点:
1、注意是否是连通图。
2、注意自环。
3、注意有两个奇度顶点时深搜起点。
以下是代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int arr[7][7]; int visited[105]; int path[105][2]; int st,end; int n,tag; struct node{ int x,y; }Node[105]; int judge(){ //判断是否是欧拉图、半欧拉图 int a[7]={ 0 }; for(int i=0;i<7;i++) for(int j=0;j<7;j++) a[i]+=arr[i][j]; int cnt=0; for(int i=0;i<7;i++) if(a[i]%2){ st=i; cnt++;//如果是半欧拉图 将深搜起点改为奇度顶点 } if(cnt==0 || cnt==2)return st; //如果是返回深搜起点 return -1; } void dfs(int v,int k,int ii){//深度优先搜索 if(tag==1)return; visited[v]=1; char ch = k==1? '+' : '-'; //k为1代表不翻 k为2代表翻转 int t = k==1?Node[v].y : Node[v].x; path[ii][0]=v+1; path[ii][1]=ch; if(ii==n-1){ //如果是连通图 输出路径 for(int i=0;i<n;i++) printf("%d %c ",path[i][0],path[i][1]); tag=1; } for(int i=0;i<n;i++) if(visited[i]==0){ if(Node[i].x==t)dfs(i,1,ii+1); else if(Node[i].y == t)dfs(i,2,ii+1); visited[i]=0; } } int main(){ //freopen("1.in","r",stdin); while(cin >> n){ for(int i=0;i<n;i++){ scanf("%d%d",&st,&end); arr[st][end]++; arr[end][st]++; Node[i].x = st; Node[i].y = end; } if(judge()==-1)printf("No solution ");//不是欧拉图 半欧拉图 else{ for(int i=0;i<n;i++) if(Node[i].x == st){ dfs(i,1,0); break; } else if(Node[i].y == st){ dfs(i,2,0); break; } if(tag==0)printf("No solution ");//不是连通图 } } }
以下是测试数据:
sample input
17
0 3
1 2
5 1
1 4
2 1
0 2
3 4
3 5
4 3
5 0
3 4
4 0
0 4
4 4
1 4
0 4
3 1
3
5 2
0 5
3 5
4
5 2
5 2
5 4
2 5
9
2 5
2 1
2 1
5 4
5 0
4 1
2 1
3 5
3 4
14
2 5
4 1
5 4
0 0
3 0
5 4
3 0
3 2
2 4
1 2
5 3
3 1
4 1
2 4
sample output
3 +
2 +
5 +
4 +
7 -
1 -
10 -
8 -
9 -
11 -
17 +
15 +
12 +
13 +
14 +
16 -
6 +
No solution
3 -
1 +
2 -
4 -
4 -
1 -
2 +
3 -
7 +
6 -
9 -
8 +
5 +
5 +
4 +
7 -
8 +
1 +
3 +
2 +
10 +
9 +
6 -
11 +
12 +
13 -
14 -