|
渡河问题
* b0 g+ Z& A9 S5 w I+ ^5 U' i 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? 9 ]( k, |8 G5 _1 F( e ?
0 v+ n5 z/ \. O5 h# C: |6 H( n程序代码:
$ {% R* }& M0 N//以下程序在Win98+vc6.0运行通过
) ^3 L6 O: ~' G, H#include <stdio.h>. P1 W. i% Y' f% P
#include <stdlib.h>+ f, h, i2 a4 {) p
#define MAX 50
0 i# W# v5 u0 c, J2 \& U6 Astruct state
, ~7 Y2 I2 B0 p$ A- z{
& y; U; p8 b2 ` int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸
; j5 g/ Y' U2 w2 W: Q' Z int m;//所采取的过河方法,(1--4)
' n9 T: N$ |* ?}s[MAX];% v$ M q! x0 b2 Q' g
int count=0;
s- c4 T" G3 z" G3 `6 t0 iFILE *fp=fopen("c:\\2.txt","w+");
) ]. M& W1 O" |% u9 \2 `% {void main()
Q f L% w+ L; h; l& C: q{
0 e* i/ L2 O6 c) F$ y void f1(int ),f2();//f1试探递归/ b) T! i, a) y- f$ [1 ?
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
, K, [# ~ v" h8 {$ l s[0].m=4;
9 H7 A0 V7 E5 g* J5 W s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;
. i* ?: Z% k% ]0 k" C f1(1);
4 F# s% l: _7 I+ Y5 z/ J //f2(); t, b8 H% |' U$ p1 U% g2 `
fclose(fp);
0 V5 z# t+ r& Q8 S8 T% {& n printf("\n"); ; z6 K5 ~: ^% G- T# d f1 V" s
}: `7 |- [. I, N
//用m值决定的方法渡河,成功返回1,否则返回0
* s) p: k2 r% ]2 P3 W2 H3 c$ cint move(int top,int m)/ x. ~. m* B" G4 @$ u
{
- l8 K: q- Z% ]. a5 c0 V switch(m)7 b, v' m1 m% D0 p8 `# X$ m
{
/ J: b( D& F% e. b. }9 J0 o //人带羊过河
* R# s: w1 C: P7 s; i/ c2 @* B case 1:
4 I( v8 `! [. @+ e1 w% v6 v+ [ //判断人羊是否在同岸6 J8 h4 Y5 T" G y+ `% S
if(s[top].man!=s[top].sheep) : F6 Z/ j' A7 V6 k7 T- x" M
return 0;/ D" D# F$ ~+ X$ Q& F
s[top].sheep=s[top].man=(s[top].man==1)?0:1;9 N, Q9 Q; W5 E v0 h1 \
s[top].m=m;//存储过河方法
. k3 o; x# E9 e% |4 t, Q break;" D! b+ D1 l& e1 [
case 2:! w! _1 t8 D4 I) }3 u3 v
if(s[top].man!=s[top].wolf)
- h4 S! w) z' R8 L2 _" X, H" m return 0;
" E D% l0 }- E- m- f1 k. G5 ^4 G s[top].wolf=s[top].man=(s[top].man==1)?0:1;1 Z. _9 O' h6 L
s[top].m=m;//存储过河方法
2 A- @% F) ? u' m break;4 B2 B' B6 J. G! R
case 3:
; h. ?9 P2 k! [& y if(s[top].man!=s[top].cabbage). F' Z$ c# t* h6 n: J$ D2 ^: E2 p$ \
return 0; s9 F, t( q) [$ w! l
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;
; C: Q1 J6 y( c5 S( R# w+ u5 k s[top].m=m;//存储过河方法
% C- X* G! Y/ u( q break;
* g9 m7 H( y( m2 Z9 W9 {1 W //人单独过河
8 v4 P. C' _' s case 4:
1 |+ v9 W9 j0 Z% d. F7 U s[top].man=(s[top].man==1)?0:1;+ f# g6 e, [4 { Y1 _
s[top].m=m;//存储过河方法: W) E& D2 f$ e8 M+ X' S
break;
" m+ G6 d0 B, I: x& N }//switch* S9 X3 x3 X1 p4 b( g& X2 O: R
return 1;) U" w9 e: W1 P; G T p! a" ~
}//move
! _+ P: Z4 `7 D, E, D//打印过河步骤
5 H ]2 X/ M) `- J3 x: }* Kvoid display(int top)
" |9 |$ G: n' V1 x{
% T; l3 x: t( F1 K int i=0;
& q" Q) K( C, H fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);" @ q6 o& {2 M' P- k" q" M
for(i=1;i<=top;i++)
" S) q& E' A4 z& i, v9 h+ A) U {
* l6 d/ A* J$ s switch(s.m): }4 u, o( r4 f0 X
{0 z. C+ T$ x I% \& N- S) \6 {, P
case 1:1 h' P2 M, j* }- u
if(s.man==1&&s[i-1].man==0)4 t0 [8 \% a" c; M9 l8 W
fprintf(fp,"人带羊从起始岸过河到目的岸\n");' _# @- t+ M* Y4 @* Q1 J
else
; K: c" X/ Q$ p0 R- A fprintf(fp,"人带羊从目的岸过河到起始岸\n");5 H8 ?/ ]) i7 u; U
break;
7 @! A8 s) G* ~; D+ w9 l$ J. w. T; s+ W case 2:
5 s. l# H' N! e( h+ s/ s o. ^3 V: u if(s.man==1&&s[i-1].man==0)+ Q+ `! i& A& Z& q; b: O
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
2 F0 x6 D% Y) @1 j. ^5 H; B, i6 w else$ u/ f# z* k. i! |
fprintf(fp,"人带狼从目的岸过河到起始岸\n");
" M( s3 v9 |5 l# p5 Y% u6 n c break;8 t% h5 E: H" h5 p- B6 M
case 3:5 y) h5 u- N8 Y( b( R5 F9 c9 L4 }' @. y
if(s.man==1&&s[i-1].man==0)2 Y, J, M& Q9 Q. j. R G
fprintf(fp,"人带菜从起始岸过河到目的岸\n");
& v, a9 u; z3 v6 u3 T else
7 x! w% P' Y$ F0 ]4 U" s fprintf(fp,"人带菜从目的岸过河到起始岸\n");# d" }6 Y& l# Y9 U: o% `, T
break;3 ~3 N8 s' c8 k7 i. Y
case 4:* ^ e( S0 p) g) ^+ j# S
if(s.man==1&&s[i-1].man==0)
" f1 N- e# @2 J. h2 A6 q! Y fprintf(fp,"人单独从起始岸过河到目的岸\n");
% {: o9 X& P& j3 K$ w" A M4 l else; {! r/ u6 k& T8 V9 z
fprintf(fp,"人单独从目的岸过河到起始岸\n"); |3 q0 j/ e, C: }5 z2 z+ L+ l p- c
break;* i4 E5 S" D( g. N1 z
}//switch
0 k( V$ p( }: K% }7 A/ X fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
5 f0 _: |8 l, A& z& @! T9 ]; f& X " J- K! ^1 f# r# v i
}//for
. r& B: x3 I& {4 ^6 J7 M0 A9 |fprintf(fp,"All ferried successfully!\n");
N. y, i% `/ D3 n' J5 }}//display l. e7 o3 q% ~0 L. P/ Z
//检查两岸合法性已经有无状态与历史重复性+ _9 _3 s0 @9 r( E
int check(int top)& _+ `. Q1 G, r$ N$ q% m
{
2 P# }. W. i; N# k: p+ |+ J! I int i;5 A/ Z* t4 q( L# q
//检查两岸合法性* ?+ P4 R8 D, J1 R0 [
if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
' U& ^6 q$ y3 W (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))% y) Q9 l7 O" ]& ^7 P; I
return 0;) `1 I0 G F ^! `* J+ `2 W7 i
//检查历史重复性
/ j# t6 l7 v7 ?1 u5 W for(i=0;i<top;i++)
: d, l0 y; Z) [- e2 M if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)
: h1 q6 Q6 H- t return 0;
! S& p" u7 v8 U- D //ok, E q. F) f& j
return 1;
6 a; C9 F# g3 [/ u y: \" c+ u3 I}
O- P% w5 x& n1 Xvoid f1(int top)
' S/ ?5 Q. Z* D3 A+ j2 b{
2 ~, W- ?: |4 v int m;
0 ^) b# u5 V6 m, j: Z: K0 ? if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1% }7 G1 A' c7 ^
{ //对每次状态分别试探4中方案: }+ p$ f7 ~ \2 x3 |6 ^
for(m=1;m<5;m++): L& M2 j4 T0 b/ x
{: K* g% d7 E+ h# ?2 T8 U$ d9 l
//每次方案的实施是在上次结果状态上做的, O0 y1 U, R1 A& ^5 L% n5 H
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
9 ?8 Z) H9 h+ x' c- l/ x s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
y, w8 V* H( Z$ y //用方案m移动,同时检查结果
, u' | n6 k1 d" M- O, g) A* @ if(move(top,m)&&check(top)), i( B* J4 a9 }: m. G
{; h; M! n2 M! Q# m3 t- I
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ) f: |. `% g W) T/ c0 d
{ `) w) a# X( C
//打印渡河步骤% b4 c- w6 C3 j; {* j! [
display(top);" O, c' g1 J, L+ t
//统计方案个数2 o! [* H, o, f X& W2 X9 d
count++; & V8 j" d! ~" Q: X+ T9 s
fprintf(fp,"count=%d----------------------------\n\n",count);
' T: i) M; X. w" l" b, x if(count>1000) exit(1);
2 J7 M" H% E4 L+ ]0 S }
8 _) e9 x* h+ @) f& U5 A+ {+ Y else
6 e* A' w8 c. {+ ^ f1(top+1);& D% i* }/ P: g x: W" j
}7 Y9 O% J6 G7 t6 P. p
}//for
, z! y7 z n: u7 Q3 v5 w9 ^ }//if(top>=0)
8 q+ n P6 q6 k6 ^1 H% U5 A}//f1
' R4 H! X+ B. g
4 l7 E- Y+ U6 T9 U$ c
+ d1 E' s: A, @, x
& u0 n1 X. s$ q% Y+ Ovoid f2()
. x7 N' O E9 x* i2 ?# b- e- ^{0 w5 D, d3 [. ]% v2 w
int top=0,i;
2 F$ u, W2 P9 r7 F //开始时都在起始岸3 G% u0 a. p8 |9 j' Q
s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;
5 h' `/ Y$ f( Z //未开始渡河3 j0 e% _: m7 Q1 C1 e
s[top].m=4;
2 E- w8 `" T5 K2 i* k while(top>=0)/ q X3 X# R4 i @& R
{
# R. {5 Z3 o( |0 X* L4 \ if(check(top))
' P5 ?0 P$ u: d: U8 v$ E3 i {& z: x# n4 T% r; t: |/ o/ C% V
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
2 w+ q: c8 |+ |; [- s {; v/ n6 x2 ~5 X) F4 M; H
//打印渡河步骤
* ^6 [( e" m @5 w display(top);; b5 x" _( C1 S+ T. P
//统计方案个数. L* q. J' h; d$ r" ?& Q/ Y3 g
count++; 6 n5 @& P/ o1 l6 v! X: a
fprintf(fp,"count=%d----------------------------\n\n",count);' e! y* k2 {' q3 P! g
if(count>1000) exit(1);1 |0 o9 b2 H9 O/ K
//回溯& X" V( q' F2 |" W. ?0 l
while(top>=0&&s[top].m>=4)
" w5 v; Q+ e4 a* ~# F! J" V top--;7 O. e$ Q! _4 P
if(top>=0)
( x0 ~3 U0 c3 j! q# \ {5 }5 V8 [4 E. a6 V3 S
//在上次状态基础上准备做move x+ x9 q' A9 \; t" m
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;1 G! ]/ b' C. R8 R- G( k, G
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
2 r, v' b: l% C3 t; s9 Y& q' f i=1;
2 E1 x$ ]3 W3 A r' Z while(s[top].m+i<5&&!move(top,s[top].m+i))
9 D# Z {5 m. _) W0 @) c i++;; p7 g, P0 ]' _
} 0 k3 Q' g8 t. ?
}
' J2 a8 h" E2 {1 h9 A else
9 Y! S# T7 J( N. t9 b {
# M# t+ l" ^8 k$ @% M& m% J top++;
" v6 U# h/ q$ A, G( u0 S //在上次状态基础上准备做move$ X3 C: ]" D+ {2 u* c0 @! r
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;" f5 L- y; y+ w/ w5 T" Z
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;9 z: U4 d% s4 g" R: {% F5 n" [" M: c
i=1;
4 M# n3 ]3 K. U& J while(i<5&&!move(top,i))
' }6 ^ b' ?/ s" R+ A2 w9 p+ g i++;
8 Q2 Y# G9 q" }7 U }
! t7 w1 `; f. j8 s }
6 @) }7 H" _7 o8 C9 O+ A, R else
2 a6 J u' [/ G* o- {4 { {
: v6 \$ P+ Z1 a1 w0 | //回溯9 n( x% X# q' U
while(top>=0&&s[top].m>=4) @1 B! t7 I8 E5 w$ U2 r
top--;5 j: U; G# r' W
if(top>=0)
1 q' Z; `2 U9 i! K6 { s {$ f4 W! o& w$ z* J( b' W o# d
//在上次状态基础上准备做move( e# P0 M# b& U1 }, ]( V
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;3 f- F- }5 W; |# U5 B1 [1 K
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;4 `9 W) x0 k4 {# `4 o5 T$ [% M
i=1; . T! V' O( |# F% p
while(!move(top,s[top].m+i))% C8 \ E: _) o/ X- p5 n
i++;
, d/ ^; R$ K. l+ u' Y& T( D: N }0 t' s }% k0 G: p8 W& o, f2 j0 ]
}
$ u q$ C K: J7 |2 j/ a }//while9 O) O' \/ L+ \0 b
}//f2
, O/ E4 K/ C- M//---------------------------------4 \: }+ ~, x% x
|