|
渡河问题 . f* c; o, h6 i* V
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? # l R$ E6 p& |, f
! ^7 @( m% x6 o" | W, u程序代码:
0 l9 {2 n0 c" n, _7 f' ^% z4 ?' ?//以下程序在Win98+vc6.0运行通过
/ Y4 s! i, L5 h$ y: j9 t( H#include <stdio.h>
9 c% ?0 f+ K* \8 ?) S#include <stdlib.h>
4 F$ I: ]9 J7 y#define MAX 50. {% `! b: D( C/ o; Q2 A' O
struct state/ J9 Q }/ {$ I9 e, }
{
# ^; n4 [& |% K4 l# M int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸
+ ]3 U: t2 |( i* h/ p+ [4 e( b int m;//所采取的过河方法,(1--4)4 c. W6 y8 M# x$ y5 l
}s[MAX];
; V5 i; g2 ~9 F# n9 r1 [1 Vint count=0;9 O& M! ^* D1 Y
FILE *fp=fopen("c:\\2.txt","w+");
3 [3 `9 \5 T& F5 ~" E" n, G- Y- {! fvoid main()
3 `- a3 J0 i7 X; _{7 N( h K( P% S! h, {6 B
void f1(int ),f2();//f1试探递归" f' X6 O# |, t4 G0 ^
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
# y& z* }2 w$ b/ w5 P# z s[0].m=4;7 x; v c( Z6 O7 G# s! ~$ q
s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;/ ]; Z3 ?7 I8 u5 |; O6 `
f1(1);/ b! j% w" K% q( e' K% o; ~5 T
//f2();$ e8 u' _- J' K5 _0 { C0 |3 D- \
fclose(fp);$ a/ ^1 o% P( Z9 w* b# @; ]/ z
printf("\n");
& [7 T$ w- ~% j! j; E+ ]}- U7 t W* s! ?% p
//用m值决定的方法渡河,成功返回1,否则返回0& W- ]$ }. r2 m/ M
int move(int top,int m)# [# v) j3 X" j3 k! x3 J
{
3 k _; D9 v8 D, N# H- \ i y switch(m)
" r! R6 r' k- t {& U/ f% H$ E& ?7 {
//人带羊过河, j% i% g( h7 M, @4 G k: B
case 1:
, S, a1 M5 f1 F8 b //判断人羊是否在同岸. R+ q/ i" X8 S" O
if(s[top].man!=s[top].sheep)
1 S1 h% A4 `9 `8 A( T/ n" } return 0;- T3 P D! V4 L8 n, a- {
s[top].sheep=s[top].man=(s[top].man==1)?0:1;, |" P; `6 d2 [$ l* Z* ?* W8 n
s[top].m=m;//存储过河方法% l5 _% v6 Y2 ^+ X
break;$ V1 g% D! F) C/ }! I2 C( K1 b& _7 z
case 2:/ g+ ^, w0 E! N0 R5 _ {
if(s[top].man!=s[top].wolf)
! c; e( Y% f" A9 t4 y: w return 0;
! f9 m) Y( b8 f$ k' [4 V s[top].wolf=s[top].man=(s[top].man==1)?0:1;3 u0 u5 ~0 i1 ~
s[top].m=m;//存储过河方法
2 j, v$ D/ r9 O7 {! n: d% | break;
$ Z" H- |# g# j% R! Y: Q5 l case 3:$ u+ a. h" N9 x
if(s[top].man!=s[top].cabbage)
4 R0 W0 P# O& ` ]. ]* h return 0;; F: f+ B P& q2 o; u& M0 o& L
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;; i& K& C3 {- q! R( X1 ~
s[top].m=m;//存储过河方法6 \' k4 l- E- \& P, c6 Q
break;8 |2 U' l% `- c a- v5 p
//人单独过河
. W: `. b. H* h/ m" a) D case 4:
$ b5 k/ I3 I, [9 E! H) ?5 O s[top].man=(s[top].man==1)?0:1;8 c+ r% ^% F, g8 f
s[top].m=m;//存储过河方法
- T9 ^, r$ `* I2 [4 d break;
3 c7 L% @0 @4 L. N$ B) o; t9 S }//switch
" u* ]3 u# w3 L) X/ e return 1;
8 D/ Y4 d( L3 ^7 e}//move; ^" V2 D0 f. v/ a9 U
//打印过河步骤* h( V! E+ H) o
void display(int top)" m6 F7 `& W1 [; R/ j
{
* s. O/ A* C0 s0 I int i=0;" q9 }* w4 | S* _" y& |
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
6 @( X7 W: S1 c; z8 W" e2 }. Z for(i=1;i<=top;i++)
0 }8 }% ~$ @8 R, O' o. d ^ {
) N4 a; ^+ u0 k5 q switch(s.m)
& ` K; G, F$ T" B. K3 Y {' f, @! Y5 R; ^9 b |& L
case 1:
4 q$ w1 B% x8 ^2 }+ A/ u, ~ if(s.man==1&&s[i-1].man==0)
9 v/ U2 u+ ?3 S- I1 p* r6 o5 [& x fprintf(fp,"人带羊从起始岸过河到目的岸\n");
V' f3 V. O' K else( d P8 S w1 X: w
fprintf(fp,"人带羊从目的岸过河到起始岸\n");
/ g: q, o( x. r4 J! \& @ break;
! y" g5 {9 u6 f/ P case 2:
3 B% M0 R$ Q9 ]7 k) ^3 e5 g if(s.man==1&&s[i-1].man==0)! x/ A" S* `& Q
fprintf(fp,"人带狼从起始岸过河到目的岸\n");9 ?8 ~! T6 U$ _4 g, M, s
else. D* C- h9 E- m& ]9 z" k# ~6 ]3 ?
fprintf(fp,"人带狼从目的岸过河到起始岸\n");4 O" a) e4 K0 x* ]3 }8 a
break;
; q- Y& f a Z. j case 3:% G/ L7 M% I! h( ?% c. j
if(s.man==1&&s[i-1].man==0)# ]! v0 n, w4 [* l- k& t% }
fprintf(fp,"人带菜从起始岸过河到目的岸\n");
* Z7 L9 @; h% b2 j- q% o& | else
. I2 y% P2 v2 Z2 t( Q; C$ g fprintf(fp,"人带菜从目的岸过河到起始岸\n");6 N- ?# k1 y% Q- e1 b' D9 \; y
break;: l" y% J: s5 Q) f! ]8 n
case 4:
$ P+ p. W' A: ?* n3 s if(s.man==1&&s[i-1].man==0)
7 n: x$ O$ U& ]. |- |! `1 b1 A) Y fprintf(fp,"人单独从起始岸过河到目的岸\n");
& ]$ P" U+ k! U, q3 u else
R" a3 q. `3 e5 U+ [' M fprintf(fp,"人单独从目的岸过河到起始岸\n");
& G- C! ]6 P4 ^) Z2 ~) M$ _4 h; W% s break;0 U! K# D/ w1 ^
}//switch
1 p' N) d" Y: D: N- p5 I fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);6 P, O; H# W/ Y$ _$ }
) n0 N! o6 S- i' f+ x- O. i* i$ N+ J }//for D; @; m- A! T
fprintf(fp,"All ferried successfully!\n");8 U( V' T2 \+ Y
}//display
( t4 \3 Y/ F3 N6 g//检查两岸合法性已经有无状态与历史重复性0 l/ i/ e& w% o$ D1 h+ H. m, b% e
int check(int top)
9 W1 e8 }2 f7 f. ^( a( w{
% k' l* h8 R; K' A int i;
& n0 V& [5 s1 \//检查两岸合法性
; T4 _5 p7 z4 o" R. F' M( g1 [ if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||" z: [: O( g" \& w
(s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))
! L" C2 O* Z, A; g x return 0; z& F* _1 X, n# u& e v. f
//检查历史重复性
9 J, q* ^$ W# ]5 G for(i=0;i<top;i++). G- ~' w, j$ F4 n
if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)
* q! I# C! P: B) S( q4 o/ z return 0;- V; @4 K0 h% _' Z% v
//ok
6 s9 E% f3 q6 L+ p" C return 1;3 O7 s. Z$ e* F
}
% r1 L# w/ `; i: B. U2 p7 wvoid f1(int top)
/ }* g/ w: [6 p6 r/ ^{/ ~. I- b, u" |
int m;
2 g( e* u+ o4 h, l2 H5 v0 g if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1+ y0 d, v- D0 k" f, R6 c: S* c
{ //对每次状态分别试探4中方案& Y- h8 G5 [. l6 {
for(m=1;m<5;m++)
0 b0 L5 [8 a Z6 N9 \$ F+ g {
% e1 b7 `! h: k* j) z o/ a //每次方案的实施是在上次结果状态上做的
' z4 K: d f+ D2 p s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
1 {3 D- Y5 E6 ?& s8 l7 j9 x s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
) g' {6 q% l3 S" o/ t! ?. a //用方案m移动,同时检查结果* d& u! s9 A" F8 _2 ]1 ^) i
if(move(top,m)&&check(top))! { g, T5 N a, |
{; j, ^9 u: S* D, N2 y" V
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ): a9 R4 S/ \: p$ g8 S0 Y
{
. ?$ N% L! j) ?1 z+ q! y# A/ @, B //打印渡河步骤
- m- T$ d5 u- a1 J display(top);: {; F& Q$ E& o- T1 y) E2 t" M% q6 v5 a" n
//统计方案个数( Y9 R. n% h* R! d% _) s
count++;
/ A( K' k+ ]. |! W% J fprintf(fp,"count=%d----------------------------\n\n",count);
# c1 y# }# J" z% {9 r- T" F) \ if(count>1000) exit(1);1 Z0 k( }% ^2 v7 P# b: b
}+ ?( h7 D5 e$ a
else5 e8 T% U) d0 u- f& _. f N& E
f1(top+1);, E1 i1 b# @* x/ L3 Q+ e/ C
}
- o+ N- @9 U, D/ c+ B' [ }//for
& J7 W* C" f$ I1 f# i$ ^+ x }//if(top>=0)
' v" O6 ?3 N1 r& }# ^$ u}//f1 7 v- P& y9 g7 Y/ q6 T
/ t0 {9 c9 }' K4 g; {1 G7 V
+ g* Q$ N! @% S# ?( \6 v ( `8 y: n2 G9 t _5 o4 I, ^
void f2()
2 v+ n) U9 @% y& P{1 l" z6 o2 x5 J# O0 a
int top=0,i;
2 f6 i8 O5 \* l" j0 c; p8 V //开始时都在起始岸2 a# g7 U& C( D; A4 `6 Y
s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;4 G! k6 J, G* V6 f+ Z6 F$ h
//未开始渡河
& B e; q1 t0 E& O5 [, l6 t s[top].m=4;' x! }2 V/ Z1 l8 q! c: I/ E, ^
while(top>=0)1 J9 e4 c, Z4 O0 L) p* r
{( @& ^; w1 D1 F% V" G
if(check(top))" i* D. Q8 \# u$ R; h
{% Q! q% j" u5 k+ j% a+ h
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )" k6 e$ \9 D9 o
{
* j6 B' {4 Y5 L. } //打印渡河步骤3 U& B& u& U- Z
display(top);, v2 K2 y1 }& j9 ~9 S
//统计方案个数
8 g' n9 N% A+ } count++; ' J8 ]2 y, j3 f% O
fprintf(fp,"count=%d----------------------------\n\n",count);
/ m+ g8 y- ~- ~8 Y/ Y# ~3 m+ ?% E H; Z if(count>1000) exit(1);/ t" ^/ `2 J, f: ]0 r
//回溯
f9 R% @ R+ N while(top>=0&&s[top].m>=4) ' a3 J1 x2 a& ?- z
top--;/ s2 n1 Z3 P! x3 L8 m. k
if(top>=0)/ F$ b" i a6 f/ O! X- e
{
$ c* w. Q, E( }- T //在上次状态基础上准备做move5 T: |1 N& V& F6 B
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
! n0 o" k- k$ ^ s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;! t& F4 D L- ]; k
i=1;
' G4 l' [# a# k! T while(s[top].m+i<5&&!move(top,s[top].m+i))- M. j. z! X# L9 |" `; R7 ` g
i++;$ a: L5 c' v4 c6 ]& P
}
0 A' S2 M9 |6 J, d) l }
& O- l: H4 B) @ else
: @7 f2 O( k8 D$ g {, d2 H) z- i" R& X
top++;% W- \& X. `+ V; k* {3 o5 g
//在上次状态基础上准备做move1 m( ?* z5 R9 J# W$ U
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;+ W' j( y+ R4 }
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;0 w1 U$ D9 n2 U* b9 S6 t
i=1;
5 i V2 w, E$ H/ z while(i<5&&!move(top,i))
- K" ]1 Y7 ^8 t9 @: m0 ^ i++;* c( ^. e/ d# G% H/ M% A- r; z
}
) G% z) Y* s1 F& z) _5 ?% v: j }
) @/ S( {8 x, j# i" U9 r% U else
5 }8 D1 ^0 I) x- L& j {+ C+ ?, o2 [, k8 \
//回溯0 P7 }+ a& w1 w
while(top>=0&&s[top].m>=4)
/ O4 ?2 t8 A/ Z% z2 I top--;
C, Z" R5 j! I9 {7 u: g if(top>=0)
$ g8 A$ |1 z! A3 r+ l9 y% b {
4 Y: I1 X/ A! t: _5 D: X1 g2 c9 X //在上次状态基础上准备做move
2 X2 f* H8 D8 o. j; s! k/ \ s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
8 j. g9 j# M8 \' n5 } d s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
" y& q) ^1 [+ {! C- K. F i=1;
' O- [" C' N# E0 ~& e, `; y' | while(!move(top,s[top].m+i))) I/ v1 e7 y3 d' M& }& k3 V0 G
i++;
) \4 R4 U! {& u8 H7 P! g }
7 C, d: c" A4 L$ i# t# I3 {1 m }
/ K) v r8 l1 d6 n j: t5 w, `, n }//while
7 \! `) a8 J. S% e' L4 j2 n}//f2
/ o" G3 z G% {. x' i- [//---------------------------------; w' a& o% t9 ?8 w5 B3 i
|