|
渡河问题 ) M+ g. f( {. l( o, F. `
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? ' ~' k* Z- h" i" H
% v! j, k& S* t7 c. W
程序代码:
/ R# m( R) ?5 g! N0 i//以下程序在Win98+vc6.0运行通过 ' J* M5 S; D' z0 n
#include <stdio.h>
9 f L2 s3 R4 C5 X% W" p#include <stdlib.h>
- c4 {% W* G/ S' F2 S7 o4 ^: _#define MAX 50
0 S/ J6 t# U G( G: nstruct state
& S& N' @; z# p& b* O{& I6 E+ N0 h, o6 Z
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸) H4 i" C' \4 q+ X/ f
int m;//所采取的过河方法,(1--4)9 Q8 S/ ?6 e) L5 q! Q5 H
}s[MAX];
( y5 _! N& S; R1 E M1 ~int count=0;
# V2 s' m7 X0 f4 ZFILE *fp=fopen("c:\\2.txt","w+");
- q7 G) n4 G; B! Z% U# ~! T! L1 Qvoid main(): J0 o$ N, t% {( o v! K, q
{" N- N2 f( t" g t- _
void f1(int ),f2();//f1试探递归
4 l0 E: C& Y! M# r s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
) A# O( t: b! ~ s[0].m=4;; k7 \" F2 y: o$ T; |
s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;* J: b3 M3 J$ F' n3 g3 V2 i2 @, Z
f1(1);
5 I2 d! A( P: I' m: M7 M5 K //f2();
' j% f8 E/ c" f) {6 E/ T$ K fclose(fp);
9 W7 M; q) R& ]1 b K printf("\n"); 1 Q$ a: S0 z% d9 h
}. M @" O D9 L) |, b# x
//用m值决定的方法渡河,成功返回1,否则返回09 Y0 ~$ H: W' L! f, Q
int move(int top,int m)6 f0 G' Z& w: t
{
4 ?0 J7 `' u8 j# N3 Q# E0 H switch(m)
0 r4 Q! t. O4 R {
3 g/ I v+ w3 ?9 x; p# q //人带羊过河
J k7 I& l% |$ u( W case 1: $ _$ K% a! p k. q% X
//判断人羊是否在同岸
) R' u3 _2 _" [0 a. f if(s[top].man!=s[top].sheep) 2 H2 D! \! a6 o
return 0;& {2 m s7 j1 ]4 C+ t) C
s[top].sheep=s[top].man=(s[top].man==1)?0:1;
; `' }3 H9 z( s( a. \* Y s[top].m=m;//存储过河方法, ~8 g5 f* z3 \& |% `# t
break;: z2 S5 I. G7 a; J' x. ~
case 2:
: ]% Q1 \. g# ~5 x- A2 w if(s[top].man!=s[top].wolf)
5 @. i e9 ^6 p" Z+ V, ] return 0;( }* ~( i5 e, ]4 {% ^7 @
s[top].wolf=s[top].man=(s[top].man==1)?0:1;
3 \# e8 R/ d, T; F s[top].m=m;//存储过河方法
) z5 X# Y- S5 X% U* g8 s break;
$ A: w8 r8 }8 x" Y case 3:
$ Q# K: t0 U3 V3 R1 k! h if(s[top].man!=s[top].cabbage)+ G: p! T6 q' I( e
return 0;) O# ]" s; o; C" Y
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;
3 M. x& i! c: p6 R; A s[top].m=m;//存储过河方法
" x/ _( o$ i( E break;
! E [' A+ G, A2 W. t0 c //人单独过河
; U! D5 |0 J+ e- e( F case 4:, L- D X4 S u0 m
s[top].man=(s[top].man==1)?0:1;
5 i2 [; U8 X8 T' C s[top].m=m;//存储过河方法6 u' u. m# w$ t
break;4 n$ r2 h# A; p0 O; [0 D/ j
}//switch3 Y+ V/ v0 M$ C0 e
return 1;
" p- t0 x" ]7 a9 ~2 ?}//move
t0 y- f- n; `6 Z, R2 T8 }//打印过河步骤8 T, j4 p0 K0 `& J
void display(int top)
- d# a" I" c, G% O2 J- c* S9 w{
5 V8 H5 t' A; ^3 E int i=0;
4 {/ L! U6 O4 Z5 O) E6 _ fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);. W) q' T" G @
for(i=1;i<=top;i++)# C: O: ^7 a& W: m" ?
{
1 G0 |2 ^3 [5 S" l) T switch(s.m), n, d4 W5 \: Q# ^
{( N/ `' s- n' I
case 1:, {! l$ W7 e1 i2 q$ @& ~1 X5 i
if(s.man==1&&s[i-1].man==0)
* Z& v+ [; Z( p fprintf(fp,"人带羊从起始岸过河到目的岸\n");
: h' Y% v& C! W& ?) Q else
- _- ?$ k1 F+ R4 v5 w8 ~3 S fprintf(fp,"人带羊从目的岸过河到起始岸\n");
* B3 ~ Z* L. [3 N% o4 S8 t/ G) V break;
# M* z+ a; Y0 s2 a4 C. e/ H" v case 2:
: h3 w5 y# Q7 [* F1 p/ z. Z+ H if(s.man==1&&s[i-1].man==0)
! }* o8 W8 Q9 z; a% |9 y3 F fprintf(fp,"人带狼从起始岸过河到目的岸\n");
# c1 E, ?3 m5 r& { L else
- J. l7 g x+ {! O fprintf(fp,"人带狼从目的岸过河到起始岸\n");
2 y/ b* X* q) C+ } break;
3 C7 N. t7 S4 C l- U7 r. [" Q case 3:- B% T, R& M& i+ t8 V z S: h
if(s.man==1&&s[i-1].man==0)
! V/ s% B2 U: |+ _6 [ fprintf(fp,"人带菜从起始岸过河到目的岸\n");
6 C h% N: H. [% ]. R# J else
* }' y' e" q) c: M9 c* m$ d/ U5 U fprintf(fp,"人带菜从目的岸过河到起始岸\n");
4 F% o1 Q) X: g0 j2 Y break;/ j$ P& e: ^& L- h8 E1 m
case 4:& Q/ c# z$ i) y- @* ^
if(s.man==1&&s[i-1].man==0)' Z3 e, s; {8 U I5 x( b
fprintf(fp,"人单独从起始岸过河到目的岸\n");
9 r% [* I" X- r else- D4 V- w5 Y u5 W( J6 C# J
fprintf(fp,"人单独从目的岸过河到起始岸\n");0 B- C4 g/ n# t6 s* `8 s
break;
% f& N' |2 v2 k( M d8 T }//switch5 Y8 _' V- Z2 ^ 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+ v! u* c$ p% p% x
; B S9 h* B5 r V/ \ }//for5 x* e) `8 z- j: `- W: f6 G% K0 L
fprintf(fp,"All ferried successfully!\n");4 c7 Y1 B p9 l/ s$ L4 ~
}//display
' q* W$ m: u4 y+ S2 I) r6 s$ e6 y//检查两岸合法性已经有无状态与历史重复性( l# p8 y( ^) [8 M0 k! ?* w
int check(int top). r9 E9 ~; `! ?+ ^# T V7 X% `; U% c
{: Q0 q4 R$ T; d! v6 ]
int i;8 b1 D8 P2 g9 k9 Y8 D
//检查两岸合法性
0 p7 S" D! B* r' Z if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
- c/ D( g' t7 Y/ s (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))
9 F7 |# H( X2 ^& k1 j$ O return 0;# r" G* g3 {/ C9 a/ J
//检查历史重复性
3 c8 B0 y" f7 } for(i=0;i<top;i++)
* D' h1 g6 x# |' u if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)' q# K* y [1 Q7 j/ [# R3 `7 |5 o
return 0;
3 G" \7 i% d/ M M* f! Y //ok" S$ N5 D0 X) O/ f- E; P+ q" o
return 1;
! l8 q8 R, ^; z9 G}
8 e1 @. ? f( I% F9 pvoid f1(int top). H! X' M+ {) B( Z: v
{
8 q9 G+ b4 H8 H* L4 V' X5 p int m;) z( E" E0 A+ w/ A
if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1
9 V# n) \' P) {4 g5 U. | { //对每次状态分别试探4中方案
( m$ ?7 m/ G6 T& u) e for(m=1;m<5;m++)
% E5 |2 g# h& [- \% B3 d {
# C1 C% s( y% w2 v //每次方案的实施是在上次结果状态上做的
9 P. ~ ^5 y! Y) m- X s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;( L7 R1 k9 i* B& Q( X
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;2 m1 e& D) [8 ~9 X1 H0 u% Z
//用方案m移动,同时检查结果
! |' ^ y+ I% c \$ l( ^* G if(move(top,m)&&check(top))
' @; D$ [# F8 @ {- u2 ~+ x' }3 `' s: n
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ): ^2 G' H% @6 C3 F1 B$ o
{3 }3 v# D& i9 p. D, ]- G- S$ g
//打印渡河步骤4 T, N/ J I O. r2 T9 S2 x6 M
display(top);+ G/ i l9 U* l0 Q- h6 W
//统计方案个数
- f* o8 X9 ^) E- @% E4 e count++;
2 m! h) R# m6 w# W+ ?1 o fprintf(fp,"count=%d----------------------------\n\n",count);
) ~$ B, [% |7 P2 h3 y) T& U if(count>1000) exit(1);% n- k2 q8 |1 X# P' e# b2 T' S
}
9 l3 b3 ^: S. r3 E* z8 W! N' m* K. b else
+ Z0 y9 }( c8 f% f c+ O f1(top+1);2 g' |" s5 I" }: \4 r2 `+ V/ L' @5 x
}( h! X! y& P1 j i% @
}//for/ T6 P N. `2 H# ^5 L+ G8 h c3 {
}//if(top>=0)5 E& ^+ |* V. q
}//f1 8 r8 p$ z# P$ K* ^, M
+ l- I/ A2 j& W% x
: W" p- Z: B% j5 b7 Q! D) r' d
2 ?7 z$ ~3 [- V7 d, w# T, c* Yvoid f2()& q) g# _3 P" b* o2 a% H
{
! ]: ?: P, b- g. X, w& T Q6 ] int top=0,i;! K- a3 ?+ x- _" y
//开始时都在起始岸
: m; X+ \* ?3 b5 c5 a2 \) x s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;7 P7 O. r0 b. \5 y
//未开始渡河
% w. D" }1 o+ B0 Y9 O4 s4 f0 Z s[top].m=4;
" c7 D. t' B3 q+ _2 o while(top>=0)$ f+ ]' r4 Q" ~2 K
{0 t+ d5 r& R3 \% R
if(check(top))7 i! r$ N/ T/ `) n& L1 M% y
{0 Z) z. O8 @! t! N+ S
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )# T5 }, B- M# ~* w3 {2 P$ r' A6 @
{ Z, a0 }; T' \
//打印渡河步骤- H t: A8 s) ]
display(top);1 T9 L8 R/ l; _1 ~5 ], u+ [
//统计方案个数
- W% O' W2 X) R& x count++;
3 Y" q, u" |' G fprintf(fp,"count=%d----------------------------\n\n",count);8 }# b5 c. o4 ~5 }6 x3 _
if(count>1000) exit(1);
R' s3 u! h( Y$ B: m //回溯
' H% a; h, q$ l# l, D! p' y while(top>=0&&s[top].m>=4) , Y) A7 x/ ]" R4 W7 `( k1 ~; u q
top--;
1 x0 W& j! K6 x( y+ M+ K- m0 Q! x if(top>=0)
3 e3 V; Y' B5 j3 E4 m {/ C. B* E- e3 e, B) j. w
//在上次状态基础上准备做move
2 I( V7 ?9 S- p% r s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;- T% W1 S' L n- i- `
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
3 y. q5 g7 ]" I' V i=1;+ H) h {/ l+ C. y) n
while(s[top].m+i<5&&!move(top,s[top].m+i))
. h4 f- S1 `8 o7 g2 M# i0 u. p' { i++;$ ~ C1 z8 |4 M* ^) r3 i
} / L) y! G/ p2 a, y, F. _0 j
}: O; T- L( k2 L% d3 \0 a
else
) j* ]9 ~9 a! {) w; s {
/ Z1 T M0 A8 l: e' _# A top++;% d! k3 L6 M5 P7 c9 h
//在上次状态基础上准备做move1 ]$ \: Q: h) i) Z
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;+ l, x4 p! f1 Q K0 R5 ^- Z) a" |7 l
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
/ }/ ^2 ~/ i2 |* u/ {7 q i=1;9 V9 i& x6 O2 I8 H7 d
while(i<5&&!move(top,i))
9 E% X: j+ [ _' [$ w6 I9 G0 W4 K i++;+ u# |" e& S" @/ T4 `% ~
}
& K K- L4 o& |1 M }
4 b' n3 J7 r! r x: w else+ p$ G- d( x9 o: U `% P! ]
{
0 Z3 f1 n! F0 I5 O& B7 \& H //回溯: w0 ~6 `+ N8 k/ o
while(top>=0&&s[top].m>=4) ) r0 y4 W- n" p6 q$ u
top--;
$ a9 |$ F: ]( w5 l- ?5 i2 h if(top>=0)
: F$ X% a! s4 s7 [* _) C5 E7 v b% } {& {) C3 x0 V: O5 T; l7 c0 \. J. x
//在上次状态基础上准备做move9 f' b( }! {9 V% A" p
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;7 Q H# z8 j. H9 s. z% r
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
+ z. k+ d3 N3 `3 [3 J+ m i=1;
! i" A [' M3 ?/ }/ \: @ while(!move(top,s[top].m+i))+ h @0 W% r5 s+ b
i++;
( r# h- s& | ^5 U4 L3 ~7 d }
$ m, K2 \" E% I }7 T" D& b& C. _1 |0 l" _6 A
}//while( t# t) ^* M- v, Y, p( w/ s/ Q
}//f2
! e. r9 O7 @5 `//---------------------------------
; v9 N% e0 X! h7 n |