SGU 101 Domino 翻译 题解

101. 多米诺

每个测试点时间限制: 0.50 sec
每个测试点内存限制: 4096 KB

多米诺 ——一种用木头或者其他材料做的小方块进行的游戏,其中每个小方块面上通常标记点数或分数。这些小方块被称作骨牌,多米诺。有时用骨片,用人,甚至用卡片。
每个小块的表面被一条线分割成两部分,每一部分都写上了可能成对的号码。

在差不多所有的现代多米诺骨牌游戏中,比赛原则是要使两个标有相同或成对的号码的小方块首尾相接应。

——《大英百科全书》

给你一些多米诺骨牌,每块的两部分都标记上 0 到 6 的号码,你的任务是把这些骨牌排列在一条直线上,使得相邻骨牌的相邻部分有同样的号码。骨牌可以左右翻转。

输入

第一行包括一个整数 N (1 ≤ N ≤ 100) 表示骨牌总数。接下来 N 行描述每一块骨牌两部分的号码,每行两个 0 - 6 的数,用空格隔开。

输出

如果不存在这样的方案,输出 “No solution”。如果方案存在,输出任意一种符合要求的方案。输出方案时应该从左到右描述骨牌的排列,每行输出用空格隔开的一个整数和一个字符,分别表示骨牌的编号和是否翻转骨牌,(+表示不翻转,-表示翻转)。

样例输入

5
1 2
2 4
2 4
6 4
2 1

样例输出

2 -
5 +
1 +
3 +
4 -

================================华丽的分割线 ================================

  要上学了,下午回来再发。 2011年6月4日 14时00分45秒
  要注意到这个可以转换成为图,最开始我计划使用骨牌作为节点,但是发现数据处理太麻烦了,第一节点数目多,第二每添加一个新骨牌处理都可能是O(n^2)的数量级,所以一直没有动手(如果要写可能不一定需要O(n^2)的数量级处理输入数据,但是越简单越具有生命力,果断放弃。)。所以将0~6作为节点,每个骨牌就是一条边。
  所以就转换成了已知7个节点和n条边,要将每条边都走一边,很明显是个欧拉路径
PS: SGU的数据很变态的,数量大,考虑方面要周全。此题要考虑:是否联通图,是否存在欧拉路。

#include <stdio.h>
#include
<stdlib.h>
int head[7];
int buff[201];
int *side = &buff[100];
int buff2[201];
int *next = &buff2[100];
int len;
int count[7];
int used[101];

void add(int x, int y)
{
int i;
i
= ++len;
side[i]
= y;
next[i]
= head[x];
head[x]
= i;

side[
-i] = x;
next[
-i] = head[y];
head[y]
= -i;

count[x]
++, count[y]++;
}
int ans[101];
int end;

void dfs(int k)
{
int i;
i
= head[k];
while(i != 0){
if(!used[abs(i)]){
used[abs(i)]
= 1;
dfs(side[i]);
ans[end
++] = i;
}
i
= next[i];
}
}

int main(int argc, char **argv)
{
int i;
int a, b;
int n, t, s;
scanf(
"%d", &n);
for(i = 0; i < n; i++){
scanf(
"%d%d", &a, &b);
add(a, b);
}
t
= 0;
for(i = 0; i <= 6; i++){
if(count[i] & 1){
t
++;
s
= i;
}
}
if(t > 2){
printf(
"No solution\n");
exit(
0);
}
if(t == 0){
for(i = 0; i <= 6; i++){
if(count[i] > 0){
s
= i;
break;
}
}
}
dfs(s);
for(i = 1; i <= n; i++){
if(!used[i]){
printf(
"No solution\n");
exit(
0);
}
}
for(i = end - 1; i >= 0; i--){
if(ans[i] > 0){
printf(
"%d +\n", ans[i]);
}
else{
printf(
"%d -\n", -ans[i]);
}
}
return 0;
}
posted @ 2011-06-04 14:08  zqynux  阅读(1510)  评论(0编辑  收藏  举报