UVa 243 - Theseus and the Minotaur (II)
2014-03-27 22:43
387 查看
题目:忒修斯和牛头人,这是个很有名的古希腊神话故事。题目的描述也不是一般的长啊。
估计很多人是被英文吓跑了,╮(╯▽╰)╭为了干掉他,看了3天的题目。
题目大概的意思:这有一个迷宫,由山洞和隧道组成,T(忒修斯)和M(牛头人)开始时
处于迷宫的隧道中,然后向前走。T的运动规则是,进入到一个洞穴后,就靠着右侧的强走,
就是走到他来的那个洞口的逆时针的下一个洞口处;如果这个隧道没走过,他就标记一下,
然后沿着它向前走,如果标记过,他就寻找逆时针顺序的下一个隧道口。M的运动规律相反,
他是靠左侧走的,也就是顺时针的选取隧道口,标记则跳过,没标记就标记,然后走进去。
如果,他们在同一个山洞相遇,那么T就杀死M;如果,他们在隧道相遇,那么M就杀死T。
如果T走进的山洞,发现M在他之前走过,那么他就会在这个山洞中点燃一根蜡烛;然后,
沿着M最后走过的隧道前进。如果M走进山洞时,发现有蜡烛,他就退回到上一个山洞。
求最后谁杀了谁(题目的数据满足,他们一定相遇)。
分析:模拟。数据利用双线链表储存,可双向读取。这种题目的难点就是划分子操作。
开始时,我尝试划分成两个子操作:
1.move_caverns_T(a,b),T从a山洞,移动到b山洞。
2.move_caverns_M(a,b),M从a山洞,移动到b山洞。
这样对于T,M都需要记录之前的节点和当前选择的隧道。
这样划分的问题就是:判断在隧道相遇有困难。所以想到下面的划分形式:
1.move_caverns_to_passage_T(a,b),T从a移动到ab间的隧道中。
2.move_caverns_to_passage_M(a,b),M从a移动到ab间的隧道中。
3.move_passage_to_caverns_T(a,b),T从ab间的隧道中移动到b。
4.move_passage_to_caverns_M(a,b),M从ab间的隧道中移动到b。
每次运行的顺序是:(a,b先后顺序无所谓,d,e的先后顺序无所谓)
a.move_passage_to_caverns_T(a,b)
b.move_passage_to_caverns_M(a,b)
c.判断M和T是不是在一个洞穴,是则M被杀
d.move_caverns_to_passage_T(a,b)
e.move_caverns_to_passage_M(a,b)
f.判断M和T是不是在同一个隧道中,是则T被杀
任何一种有解的数据,都可以用上面的序列求解,初始在隧道相遇除外(需要特判)。
估计很多人是被英文吓跑了,╮(╯▽╰)╭为了干掉他,看了3天的题目。
题目大概的意思:这有一个迷宫,由山洞和隧道组成,T(忒修斯)和M(牛头人)开始时
处于迷宫的隧道中,然后向前走。T的运动规则是,进入到一个洞穴后,就靠着右侧的强走,
就是走到他来的那个洞口的逆时针的下一个洞口处;如果这个隧道没走过,他就标记一下,
然后沿着它向前走,如果标记过,他就寻找逆时针顺序的下一个隧道口。M的运动规律相反,
他是靠左侧走的,也就是顺时针的选取隧道口,标记则跳过,没标记就标记,然后走进去。
如果,他们在同一个山洞相遇,那么T就杀死M;如果,他们在隧道相遇,那么M就杀死T。
如果T走进的山洞,发现M在他之前走过,那么他就会在这个山洞中点燃一根蜡烛;然后,
沿着M最后走过的隧道前进。如果M走进山洞时,发现有蜡烛,他就退回到上一个山洞。
求最后谁杀了谁(题目的数据满足,他们一定相遇)。
分析:模拟。数据利用双线链表储存,可双向读取。这种题目的难点就是划分子操作。
开始时,我尝试划分成两个子操作:
1.move_caverns_T(a,b),T从a山洞,移动到b山洞。
2.move_caverns_M(a,b),M从a山洞,移动到b山洞。
这样对于T,M都需要记录之前的节点和当前选择的隧道。
这样划分的问题就是:判断在隧道相遇有困难。所以想到下面的划分形式:
1.move_caverns_to_passage_T(a,b),T从a移动到ab间的隧道中。
2.move_caverns_to_passage_M(a,b),M从a移动到ab间的隧道中。
3.move_passage_to_caverns_T(a,b),T从ab间的隧道中移动到b。
4.move_passage_to_caverns_M(a,b),M从ab间的隧道中移动到b。
每次运行的顺序是:(a,b先后顺序无所谓,d,e的先后顺序无所谓)
a.move_passage_to_caverns_T(a,b)
b.move_passage_to_caverns_M(a,b)
c.判断M和T是不是在一个洞穴,是则M被杀
d.move_caverns_to_passage_T(a,b)
e.move_caverns_to_passage_M(a,b)
f.判断M和T是不是在同一个隧道中,是则T被杀
任何一种有解的数据,都可以用上面的序列求解,初始在隧道相遇除外(需要特判)。
#include <iostream> #include <cstdlib> #include <cstdio> typedef struct dnode { int point; int flag1;//标记T走过,取值0和1 int flag2;//标记M走过,取值>0,表示访问顺序 dnode* left; dnode* right; }dlink; dlink Node[2000]; dlink* Head[30]; int d_size; void dlink_inital( void ) { d_size = 0; for ( int i = 0 ; i < 26 ; ++ i ) Head[i] = NULL; } void dlink_add( int a, int b ) { if ( !Head[a] ) { Node[d_size].left = &Node[d_size]; Node[d_size].right = &Node[d_size]; Head[a] = &Node[d_size]; }else { Node[d_size].right = Head[a]; Node[d_size].left = Head[a]->left; Head[a]->left->right = &Node[d_size]; Head[a]->left = &Node[d_size]; } Node[d_size].flag1 = 0; Node[d_size].flag2 = 0; Node[d_size].point = b; d_size ++; } //计算下一个隧道位置 dlink* dlink_next( dlink* p, int id, int forword ) { dlink *t = Head[p->point]; while ( t->point != id ) t = t->right; return (forword?t->right:t->left); } //返回M最近走过的隧道 dlink* dlink_last( dlink* p ) { dlink *t = p,*m = p,*q; for ( q = t->right; t != q ; q=q->right ) if ( m->flag2 < q->flag2 ) m = q; return m; } //标记M到过(2),或者点燃蜡烛(1) int visit[30]; int main() { char a,b,c,d; while ( ( a = getchar() ) != '#' ) { dlink_inital(); while ( a != '@' ) { getchar(); while ( ( b = getchar() ) != '\n' ) dlink_add( a-'A', b-'A' ); a = getchar(); } a = getchar();b = getchar(); c = getchar();d = getchar(); getchar(); if ( ( a == c && b == d ) || ( a == d && b == c ) ) { printf("Theseus is killed between %c and %c\n",a,b); continue; } for ( int i = 0 ; i < 26 ; ++ i ) visit[i] = 0; int T = a-'A',M = c-'A',S; dlink *p = Head[a-'A']; while ( p->point != b-'A' ) p = p->right; dlink *q = Head[c-'A']; while ( q->point != d-'A' ) q = q->right; int flagp = 1,flagq = 1,Mmark = 1; while ( 1 ) { //Minotaur into cavern S = M; M = q->point; q = dlink_next( q, S, 0 ); if ( visit[M] == 1 ) { q = dlink_next( q->right, M, 0 ); M = S; }else visit[M] = 2; //Thseus into cavern S = T; T = p->point; p = dlink_next( p, S, 1 ); if ( T == M ) {//meet in cavern printf("The Minotaur is slain in %c\n",M+'A'); break; } //Thseus into passage if ( visit[T] == 2 ) { visit[T] = 1; p = dlink_last( p ); }else while ( p->flag1 ) p = p->right; p->flag1 = 1; //Minotaur into passage while ( q->flag2 ) q = q->left; q->flag2 = Mmark ++; if ( M == p->point && T == q->point ) {//meet in passage printf("Theseus is killed between %c and %c\n",'A'+T,'A'+M); break; } } } return 0; }
相关文章推荐
- UVA 168 - Theseus and the Minotaur
- HDU-1027 Ignatius and the Princess II
- HDU 1027 Ignatius and the Princess II 全排列
- HDU 1027 Ignatius and the Princess II(康托逆展开)
- HDU 1027 Ignatius and the Princess II 选择序列题解
- Ignatius and the Princess II hdu 1027
- HDU 1027 Ignatius and the Princess II
- HDU 1027 Ignatius and the Princess II
- 1027 Ignatius and the Princess II
- HDOJ1027 Ignatius and the Princess II
- HDU 1027 Ignatius and the Princess II next_permutation函数(也可以用DFS......)
- Ignatius and the Princess II
- 排列-hdu_1027_Ignatius and the Princess II
- hdoj--1027--Ignatius and the Princess II(dfs)
- HDU-Ignatius and the Princess II
- HDU 1027 Ignatius and the Princess II(next_permutation()的应用)
- HDU_1027_Ignatius and the Princess II_全排列
- HDU.1027 Ignatius and the Princess II【全排列:关于next_permutation问题】(3.14)
- 【HDU 1027 Ignatius and the Princess II】+ 全排列 + STL
- HDOJ 1027 Ignatius and the Princess II