Shoot_Your_Gun.dpr 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. program doshide;
  2. {$R-,Q-,S-}
  3. const
  4. dir : array [ 1..4, 1..2 ] of longint = ( ( - 1, - 1 ), ( 1, - 1 ), ( 1, 1 ), ( - 1, 1 ) );
  5. opp : array [ 1..4, 1..4 ] of longint = ( ( 2, 1, 4, 3 ), ( 4, 3, 2, 1 ), ( 2, 1, 4, 3 ), ( 4, 3, 2, 1 ) );
  6. op : array [ 1..4 ] of longint = ( 3, 4, 1, 2 );
  7. maxn = 50 + 1;
  8. maxm = 2000000;
  9. infinity = 100000000;
  10. type
  11. Point = array [ 1..3 ] of longint;
  12. var
  13. m : array [ 1..3, 1..maxn ] of Point;
  14. turn : array [ 1..3, 1..maxn ] of longint;
  15. visit : array [ 0..maxm, 1..4 ] of boolean;
  16. first : array [ 1..maxn ] of longint;
  17. n : array [ 1..3 ] of longint;
  18. ans, task : longint;
  19. procedure ReadData;
  20. var
  21. i : longint;
  22. procedure GetInf( k : longint );
  23. var
  24. i, j : longint;
  25. begin
  26. for i := 1 to n[ k ] do
  27. begin
  28. read( m[ k ][ i ][ 1 ], m[ k ][ i ][ 2 ] );
  29. m[ k ][ i ][ 1 ] := m[ k ][ i ][ 1 ] * 2;
  30. m[ k ][ i ][ 2 ] := m[ k ][ i ][ 2 ] * 2;
  31. end;
  32. m[ k ][ n[ k ] + 1 ] := m[ k ][ 1 ];
  33. for i := 1 to n[ k ] do
  34. begin
  35. if ( m[ k ][ i + 1 ][ 2 ] - m[ k ][ i ][ 2 ] < 0 ) then
  36. m[ k ][ i ][ 3 ] := 1;
  37. if ( m[ k ][ i + 1 ][ 1 ] - m[ k ][ i ][ 1 ] > 0 ) then
  38. m[ k ][ i ][ 3 ] := 2;
  39. if ( m[ k ][ i + 1 ][ 2 ] - m[ k ][ i ][ 2 ] > 0 ) then
  40. m[ k ][ i ][ 3 ] := 3;
  41. if ( m[ k ][ i + 1 ][ 1 ] - m[ k ][ i ][ 1 ] < 0 ) then
  42. m[ k ][ i ][ 3 ] := 4;
  43. end;
  44. for i := 1 to n[ k ] do
  45. begin
  46. j := i + 1;
  47. if ( j > n[ k ] ) then
  48. j := 1;
  49. if ( m[ k ][ i ][ 3 ] = 1 ) and ( m[ k ][ j ][ 3 ] = 2 ) then
  50. turn[ k ][ i + 1 ] := 3;
  51. if ( m[ k ][ i ][ 3 ] = 1 ) and ( m[ k ][ j ][ 3 ] = 4 ) then
  52. turn[ k ][ i + 1 ] := 4;
  53. if ( m[ k ][ i ][ 3 ] = 2 ) and ( m[ k ][ j ][ 3 ] = 1 ) then
  54. turn[ k ][ i + 1 ] := 4;
  55. if ( m[ k ][ i ][ 3 ] = 2 ) and ( m[ k ][ j ][ 3 ] = 3 ) then
  56. turn[ k ][ i + 1 ] := 1;
  57. if ( m[ k ][ i ][ 3 ] = 3 ) and ( m[ k ][ j ][ 3 ] = 2 ) then
  58. turn[ k ][ i + 1 ] := 2;
  59. if ( m[ k ][ i ][ 3 ] = 3 ) and ( m[ k ][ j ][ 3 ] = 4 ) then
  60. turn[ k ][ i + 1 ] := 1;
  61. if ( m[ k ][ i ][ 3 ] = 4 ) and ( m[ k ][ j ][ 3 ] = 1 ) then
  62. turn[ k ][ i + 1 ] := 2;
  63. if ( m[ k ][ i ][ 3 ] = 4 ) and ( m[ k ][ j ][ 3 ] = 3 ) then
  64. turn[ k ][ i + 1 ] := 3;
  65. end;
  66. turn[ k ][ 1 ] := turn[ k ][ n[ k ] + 1 ];
  67. end;
  68. begin
  69. read( n[ 1 ] );
  70. if ( n[ 1 ] = 0 ) then
  71. exit;
  72. read( n[ 2 ], n[ 3 ] );
  73. for i := 1 to 3 do
  74. GetInf( i );
  75. end;
  76. procedure Walk( x, y, d : longint );
  77. var
  78. min, a, b, id : longint;
  79. times, num : longint;
  80. function Area( x, y : longint; p1, p2 : Point ) : longint;
  81. begin
  82. Area := ( x - p2[ 1 ] ) * ( p1[ 2 ] - p2[ 2 ] ) - ( p1[ 1 ] - p2[ 1 ] ) * ( y - p2[ 2 ] );
  83. end;
  84. function Dot( p1, p2 : Point; x, y : longint ) : longint;
  85. begin
  86. Dot := ( p1[ 1 ] - x ) * ( p2[ 1 ] - x ) + ( p1[ 2 ] - y ) * ( p2[ 2 ] - y );
  87. end;
  88. function Cross( var x1, y1, dist : longint; p1, p2 : Point ) : boolean;
  89. begin
  90. x1 := x + dist * dir[ d ][ 1 ];
  91. y1 := y + dist * dir[ d ][ 2 ];
  92. Cross := ( ( Area( x1, y1, p1, p2 ) = 0 ) and ( dot( p1, p2, x1, y1 ) < 0 ) ) or ( ( p1[ 1 ] = x1 ) and ( p1[ 2 ] = y1 ) );
  93. end;
  94. function Dist( p1, p2 : Point ) : longint;
  95. begin
  96. if ( p1[ 1 ] = p2[ 1 ] ) then
  97. Dist := abs( x - p1[ 1 ] )
  98. else
  99. Dist := abs( y - p1[ 2 ] );
  100. end;
  101. procedure Process;
  102. var
  103. k, i, x1, y1, distance : longint;
  104. begin
  105. min := infinity;
  106. a := 0;
  107. b := 0;
  108. id := 0;
  109. num := 0;
  110. for k := 1 to 3 do
  111. for i := 1 to n[ k ] do
  112. begin
  113. distance := dist( m[ k ][ i ], m[ k ][ i + 1 ] );
  114. if ( distance > 0 ) and ( distance < min ) and ( Cross( x1, y1, distance, m[ k ][ i ], m[ k ][ i + 1 ] ) ) then
  115. begin
  116. min := distance;
  117. a := x1;
  118. b := y1;
  119. num := i;
  120. id := k;
  121. end;
  122. end;
  123. end;
  124. begin
  125. times := 0;
  126. inc( times );
  127. repeat
  128. if ( times - 2 > ans ) then
  129. exit;
  130. Process;
  131. if ( min = infinity ) or ( id = 1 ) then
  132. begin
  133. if ( id = 1 ) then
  134. visit[ first[ num ] + 1 + abs( a - m[ 1 ][ num ][ 1 ] ) + abs( b - m[ 1 ][ num ][ 2 ] ) ][ op[ d ] ] := true;
  135. exit;
  136. end;
  137. if ( id = 2 ) then
  138. break;
  139. if ( a = m[ id ][ num ][ 1 ] ) and ( b = m[ id ][ num ][ 2 ] ) then
  140. begin
  141. if ( turn[ id ][ num ] = d ) or ( turn[ id ][ num ] = op[ d ] ) then
  142. exit;
  143. dec( times );
  144. end
  145. else
  146. d := opp[ m[ id ][ num ][ 3 ] ][ d ];
  147. x := a;
  148. y := b;
  149. until ( false );
  150. if ( times - 1 < ans ) then
  151. ans := times - 1;
  152. end;
  153. procedure Work;
  154. var
  155. i, k, x, y, a, b, l : longint;
  156. begin
  157. ans := infinity;
  158. l := 0;
  159. for i := 1 to n[ 1 ] do
  160. begin
  161. x := ( m[ 1 ][ i + 1 ][ 1 ] - m[ 1 ][ i ][ 1 ] );
  162. y := ( m[ 1 ][ i + 1 ][ 2 ] - m[ 1 ][ i ][ 2 ] );
  163. if ( x <> 0 ) then
  164. x := x div abs( x );
  165. if ( y <> 0 ) then
  166. y := y div abs( y );
  167. a := m[ 1 ][ i ][ 1 ];
  168. b := m[ 1 ][ i ][ 2 ];
  169. first[ i ] := l;
  170. while ( a <> m[ 1 ][ i + 1 ][ 1 ] ) or ( b <> m[ 1 ][ i + 1 ][ 2 ] ) do
  171. begin
  172. inc( l );
  173. inc( a, x );
  174. inc( b, y );
  175. end;
  176. end;
  177. for i := 1 to n[ 1 ] do
  178. begin
  179. x := ( m[ 1 ][ i + 1 ][ 1 ] - m[ 1 ][ i ][ 1 ] );
  180. y := ( m[ 1 ][ i + 1 ][ 2 ] - m[ 1 ][ i ][ 2 ] );
  181. if ( x <> 0 ) then
  182. x := x div abs( x );
  183. if ( y <> 0 ) then
  184. y := y div abs( y );
  185. a := m[ 1 ][ i ][ 1 ];
  186. b := m[ 1 ][ i ][ 2 ];
  187. while ( a <> m[ 1 ][ i + 1 ][ 1 ] ) or ( b <> m[ 1 ][ i + 1 ][ 2 ] ) do
  188. begin
  189. for k := 1 to 4 do
  190. if ( not visit[ first[ i ] + 1 + abs( a - m[ 1 ][ i ][ 1 ] ) + abs( b - m[ 1 ][ i ][ 2 ] ) ][ k ] ) then
  191. Walk( a, b, k );
  192. inc( a, x );
  193. inc( b, y );
  194. end;
  195. end;
  196. if ( ans = infinity ) then
  197. ans := - 1;
  198. writeln( 'Case ', task, ': ', ans );
  199. end;
  200. begin
  201. assign( input, 'gun.in' );
  202. reset( input );
  203. assign( output, 'gun.out' );
  204. {gun.ans}
  205. rewrite( output );
  206. task := 0;
  207. repeat
  208. fillchar( visit, sizeof( visit ), 0 );
  209. inc( task );
  210. ReadData;
  211. if ( n[ 1 ] = 0 ) then
  212. break;
  213. Work;
  214. until ( false );
  215. close( input );
  216. close( output );
  217. end.