|
渡河问题
$ X! f3 c5 P8 r N' q' @ A wolf, a goat and a cabbage are on one bank of a river. A ferryman wants to take them across, but since his boat is small, he can take only one of them at a time. For obvious reasons, neither the wolf and the goat nor the goat and the cabbage can be left unguarded. How is the ferryman going to get them across the river?
) Y0 J5 J, F& m$ O* W 7 o; Y! f6 f3 k# t2 g' r: H
程序代码: & }4 O- A% ~9 _' I9 y: }& e/ `
//以下程序在Win98+vc6.0运行通过 8 u; W4 V9 J2 o
#include <stdio.h>; H5 a1 {. }% ?5 ^8 |3 H8 V9 g2 x$ f
#include <stdlib.h>( T1 m& X6 \- z+ \' [' j8 t
#define MAX 50' u& h9 z5 w/ l( Q4 `
struct state
$ _1 K- T% v, q: b$ I{* Z- [6 b$ [4 D
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸
) I. ]9 y& j5 v- Q X; d f& R int m;//所采取的过河方法,(1--4)8 a) f: G; p4 @2 T. S+ C' {9 c
}s[MAX];( E% {, F" o1 i( @6 K
int count=0;) v7 u" O* Q) w. P! C0 i1 @: B4 p
FILE *fp=fopen("c:\\2.txt","w+");
8 N; o% w5 S' R) z& Qvoid main(); n! t) t- O! O( \- \
{
: p. P( s6 o& V3 u0 [! x void f1(int ),f2();//f1试探递归8 b6 `+ c7 \& n4 \8 s Z7 {
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
) H5 g1 M' _$ c1 r: b s[0].m=4;9 k3 P5 H, ]4 ]3 H6 O
s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;
" q H/ [' p7 Q% M f1(1);$ E% u! D% b, z0 O! E I& J
//f2();
: u2 w7 k% v& v/ l fclose(fp);
2 a4 ^1 g; S, E- b2 _& B printf("\n");
! ^- ?) z" X& u" n}
, C1 X# p3 X0 L% |//用m值决定的方法渡河,成功返回1,否则返回0
$ x6 ~5 c$ r4 k ?+ Pint move(int top,int m)! U; \) H$ U9 R p
{, T: F% {. ` M( y. @8 \# p$ Q
switch(m)
; [+ U6 t* S1 X' j; Z0 Y {
. d4 {" t9 ^ `0 }& c- H //人带羊过河2 Q- V( J* l- ^# u
case 1: 3 q2 V; S& ~" A! m, v
//判断人羊是否在同岸
- f! T; F1 r3 C. D9 [ if(s[top].man!=s[top].sheep)
. O3 z/ `( h! Q( U0 q6 E8 N* U1 \9 u return 0;$ y8 |+ X& F2 K
s[top].sheep=s[top].man=(s[top].man==1)?0:1;# {2 E7 @& M' n. Z4 [# U( K
s[top].m=m;//存储过河方法
! i6 m* E' T* Z9 ^+ j: M break;1 Z, B `9 V4 K7 f% u
case 2:
: n0 V# N( Z5 w if(s[top].man!=s[top].wolf)
) P5 y. O7 \0 U# I0 ?3 ? return 0;
$ R9 K8 X# A7 [$ \' l$ D8 g8 `* A! A s[top].wolf=s[top].man=(s[top].man==1)?0:1;
1 {9 J9 }% c4 e9 ?' ^2 ^# Y s[top].m=m;//存储过河方法
% v2 B% s9 \! ~2 ?5 s) \ break;
4 T. j6 j# R5 }" x case 3:4 Z, {! S4 j* M1 S& N; k( A
if(s[top].man!=s[top].cabbage)4 E2 A: \4 y t5 w$ q5 [" Z
return 0;+ r4 k0 w) R' N8 J: d
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;4 A; k3 T9 g- }3 @$ `% L
s[top].m=m;//存储过河方法
; E4 T; ~- k9 J1 K7 x0 _2 w break;. q1 g5 z$ E: r6 h, p
//人单独过河
/ Y2 b/ W7 N7 `, V case 4:; u7 x3 h" w3 ^+ V: O7 q4 R
s[top].man=(s[top].man==1)?0:1;- E; P3 n) `! Q1 e
s[top].m=m;//存储过河方法. t2 |: A& W7 S
break;
' }+ |3 W4 S" A3 [# r }//switch7 s1 |8 w' B( m( V7 y/ n
return 1;' y! @( N' m# D" `0 p
}//move7 x3 V& |. z* J* k) k* b5 i4 h
//打印过河步骤
% \3 _8 i7 x) G/ Bvoid display(int top)
6 U3 |+ h7 n( |/ g1 v0 x{2 G5 n% ^% i' Y
int i=0;- c/ b ?1 h2 ?: h
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
, X/ t& L# _- {) M for(i=1;i<=top;i++)( s6 {3 l0 h2 r5 {. r4 B& U
{
2 v% \3 _6 _; x; _& c( A4 C& o switch(s.m)
9 R3 w# ^5 a, P# Y w {4 D1 o! _' e0 b/ \
case 1:4 {. V+ B4 a# J1 e
if(s.man==1&&s[i-1].man==0)8 ^, o$ L' T% m6 G5 x# O' X/ \
fprintf(fp,"人带羊从起始岸过河到目的岸\n");
( P, R/ `& A: }% _. V: V else
3 Q C5 m3 |+ H5 I. D f fprintf(fp,"人带羊从目的岸过河到起始岸\n");$ z6 G. p3 K. d2 \& E+ y
break;
. c0 ~$ W& a) w: M case 2:3 X" u$ s; h& |1 a
if(s.man==1&&s[i-1].man==0)) u5 G% r% }1 P- U
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
/ h( ?2 z- z5 t& X9 g/ F1 \* G6 n else
& [) T; T' F/ _/ _2 T5 J. ?$ \3 J fprintf(fp,"人带狼从目的岸过河到起始岸\n");
5 A5 g! g5 a2 {4 l7 D& m2 Z- [, h break;
5 W, p2 h. B( w; G6 Y+ z/ j case 3: R/ S, P# w1 n. z2 V" J+ p
if(s.man==1&&s[i-1].man==0)
u7 H3 s' ?& v9 w- p fprintf(fp,"人带菜从起始岸过河到目的岸\n");
6 h( L. o) @0 V5 i. q. h else% m% E4 {4 j" B* f/ u; E
fprintf(fp,"人带菜从目的岸过河到起始岸\n");
& c% y Z# a) W: u' U' M6 n break;$ u, G! x6 ^' q
case 4:
" \7 R' U1 O y$ ^0 ^( u6 A if(s.man==1&&s[i-1].man==0)
# h7 L! }& z, t# z3 m6 B/ b fprintf(fp,"人单独从起始岸过河到目的岸\n");
0 v$ t; H. J" E else7 j8 A2 q9 g) p& K& U5 e
fprintf(fp,"人单独从目的岸过河到起始岸\n");# D$ O, v& p% ]. N7 O
break;( a- Y8 X$ X6 E2 V3 y/ j+ G
}//switch
) ]7 {: U, y- A! W. x7 u& S fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);( m+ D/ {% G; G9 y$ f% K8 g
/ u( j) Z& T) s6 | }//for6 j" ?1 ? O F/ m/ I# [- U
fprintf(fp,"All ferried successfully!\n");2 z. `. s& `) v2 R5 ~# U- P/ e5 O
}//display
( U; d6 j; R" c1 o9 c//检查两岸合法性已经有无状态与历史重复性0 D+ Y9 I; U: {' L: x1 n
int check(int top)
O$ I% x3 A0 p. S% E' J+ Q% p- Y{
4 M% x' Y( h' {( y9 p: X int i;2 X( h6 Q' f9 Y5 j5 V- Y- @/ m7 h
//检查两岸合法性
, H# G7 V! s) T# v6 G if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
% r2 T5 Q/ f+ E (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))* V/ X# X" z8 z* o1 }& | I' a2 }
return 0;6 e5 P0 e' @. Y# W
//检查历史重复性# C$ H" T& R# F, Z
for(i=0;i<top;i++)
2 ]9 S# k' Q% E7 m if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)
) A( R; O" D- z! [+ @8 u return 0;
/ a9 E3 {; g; f$ K. M; q9 n //ok- n* X, j$ e# s5 k! R1 V* G
return 1;
: G( D, |/ J: Z4 {( O& }1 w: Z}
6 }$ x+ l, I/ T: U' ]void f1(int top)
( x; f1 t. y* U0 M9 f3 [{& |1 H1 H( S( S* F
int m;
* n8 u5 H( R* z; |( ]. G if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1: K, N+ F: a3 E3 M, [' [
{ //对每次状态分别试探4中方案$ F$ t# G3 @" [; h5 q5 g
for(m=1;m<5;m++)
! Q5 L3 b; q) ^% o+ Z: ^ {' l9 C m, C8 n6 T+ Y
//每次方案的实施是在上次结果状态上做的
' ~; v3 Z5 ]. V4 x! Y s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
$ k. @2 {- t2 Z6 Z# S5 e5 X s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;3 h% b6 \4 w/ x+ r& N
//用方案m移动,同时检查结果
6 R+ e9 a/ |' D: O2 B/ i if(move(top,m)&&check(top))
) _; I% _/ I+ r' A {
/ w+ x9 y- J% C) Q7 h: q if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
) F% t0 l4 {' C5 [: ^ {' A9 l3 N3 q2 M1 [
//打印渡河步骤! s7 u' S* F. k; ^. J! J
display(top);
b7 @. r& y. X& T( @ //统计方案个数; f+ c: l6 c T8 @
count++; , M& ~$ x: S ~
fprintf(fp,"count=%d----------------------------\n\n",count);
8 T W1 J8 S: h9 @" q7 w if(count>1000) exit(1);, [: L q( F& H0 M7 E
}' k7 X w& s: u9 }& o* u
else
( W$ a; c$ ]" g2 I6 [4 t f1(top+1);
$ @$ n7 b8 U7 i% Z4 W/ _) r6 G2 _6 w }
2 N- O; a- t, c7 B# \ }//for
; w" R& Y% I$ R' E) B: L }//if(top>=0)+ S3 S% D- Q; g+ [ [0 u( B7 e+ ^
}//f1
& U0 c2 v2 M. U$ n' L 1 O2 u z2 k2 j1 s3 h' k
' w. |/ _+ x8 ?# y # a# d5 H: S5 H
void f2()
9 W$ ~% e! E, y{ m ^3 y- d" h# }
int top=0,i;
+ `5 z1 O* m/ V+ C8 S, Q //开始时都在起始岸
+ ]/ Y0 |& W! O4 I$ ` s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;$ L3 T" r# Z+ E6 W
//未开始渡河7 m+ ~* j0 j. x7 {( q6 {
s[top].m=4;6 ~( ?3 g2 @' }% D8 g: P$ y
while(top>=0)
. x% d% g3 g, ], E0 O" ?( R {0 d# Y4 G6 d" K
if(check(top))7 `8 D% u \% E( ]
{7 h6 |% ] l- h k* k/ q/ ]
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
0 H) I# E/ T% T! w1 ?+ _ {
( }9 d3 m6 O4 m //打印渡河步骤. l0 a9 T- V0 `: N9 I$ s6 T5 a; \
display(top);5 j4 A8 y; o2 p
//统计方案个数6 H1 W! t7 V, x3 v0 s( O* b& F( H4 T, ~
count++;
5 K5 l% z! k: |# P k fprintf(fp,"count=%d----------------------------\n\n",count);
2 @$ w' {" r: J/ P* G if(count>1000) exit(1);
9 J& P- R$ X& v( W7 m/ b) u //回溯6 m1 _' a/ W: @8 l
while(top>=0&&s[top].m>=4)
/ E' t1 ^% d' Y, Q" m* a2 y top--;2 y5 L3 e, C G# w* b
if(top>=0)/ x; O( Y1 x, o. h" u
{
+ C0 R6 x$ j+ Q7 i4 c //在上次状态基础上准备做move7 t8 k& y! X ~) P7 |4 t
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
& G% U' g; e' H s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
, P1 b- F w$ r" e* e% V' m i=1;
; j3 j( X& I" F" c4 Q; P. \ while(s[top].m+i<5&&!move(top,s[top].m+i))
: u7 b! a8 S% U8 G. w i++;4 S1 r9 A: N) Q$ J3 J. _* E
} + [1 Y9 l2 r+ E: q; t( V' R) t
}
2 t% [* P7 s% K8 y else: S+ D/ X0 J- @+ N
{* r* ^$ B! s$ [
top++;* X7 ]0 v9 G4 F( N/ Z' K6 O* `
//在上次状态基础上准备做move
& Q; Q. \' u4 g8 Z6 [' g) M s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;: G3 [8 ]- `; m
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;2 u6 }( ^1 w+ r' b* k8 Y& a' f
i=1;+ a- E7 I9 |" E8 V- E! [/ s
while(i<5&&!move(top,i))
( N0 K, }7 W; F2 `4 W& x. ? i++;0 I& V) A1 r% J5 ~& t: u
} 1 A0 q! I3 D, F% p: ^: F+ V
}
. [8 o& n2 ^0 t* ` else1 E- z6 |5 e! A2 G* d
{( Q7 E$ ^0 _5 g5 N# I8 @% ]5 U7 S5 k& j
//回溯; O( b# A1 n. o. T, s, X. a$ O' C& n
while(top>=0&&s[top].m>=4)
0 s' P3 i$ _4 r3 k, y- e1 } top--;( ]9 P+ L: n* a* h8 B! M
if(top>=0)
2 U9 Y! _, H( f {- V; b2 _- p$ d) m9 U
//在上次状态基础上准备做move
c- m$ X7 L" Q. O s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;7 G5 Q$ V4 H4 o; i- u" n9 R/ H; ?* Q
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
8 |: m |, @/ `* Q4 f i=1; 5 U& t; r4 `. z* d6 w* ~
while(!move(top,s[top].m+i))
5 L# e# C! y- Y* @9 t: M i++;: G2 J* ^4 K& A- O% Y
}" M/ Q; j) D4 o% q+ H. O1 w
}7 l9 V8 B1 J2 W3 s$ _7 }7 s/ O
}//while
, u" y/ Q# w; y) P& ]! e/ q( m}//f2 {" L" C4 s E: g( a0 a# g' S
//---------------------------------6 w8 K2 n2 L8 F7 b8 h7 q
|