|
渡河问题 - o7 E2 W: h8 n
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?
0 |1 X; {! T. U " }% f7 W! V; _4 {
程序代码:
: N9 J' G' E8 Q//以下程序在Win98+vc6.0运行通过
7 a: i. \: Y0 t, G( T#include <stdio.h>- S/ t! c" m+ B* i2 N5 _' A$ K' [
#include <stdlib.h>
' L! H7 d" ?( W) ^" B#define MAX 501 l) W7 h! S, c9 q' S( K
struct state9 V+ M- c7 C$ N* S3 T5 W ?
{$ k9 Y, t) B) F3 P
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸; E7 F6 c+ H% a
int m;//所采取的过河方法,(1--4)
, F, T' s. M% w, c' K}s[MAX];
, b$ k: f" H) E- Pint count=0;$ V( B1 T- d/ B4 {. \, L1 v4 e3 _
FILE *fp=fopen("c:\\2.txt","w+"); 2 K5 v5 z2 z+ A0 X/ F" ~
void main()
# I6 r) z0 h& G. o9 \{% l9 s9 b3 O( ?
void f1(int ),f2();//f1试探递归3 @ K" o) D1 i2 S1 y
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
& N/ o/ u. Z3 A x( @7 L s[0].m=4;
+ S, s3 u. w- O3 Z+ {0 W: }5 s s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;
8 p1 D" X, [$ E, d1 I* t f1(1);
% Q0 _% j. H/ T7 e6 j //f2();
0 v) r: I. p' K" w) {: e fclose(fp);
& p5 \- }: H- {: E9 d. n6 M& ^ printf("\n");
8 G' K2 i0 G( Z1 c; M}, u" J M: f% M# T6 Y0 B; g
//用m值决定的方法渡河,成功返回1,否则返回0" x8 @) V+ S! h @0 `- t: B
int move(int top,int m)
# Z7 z- d j! R' d2 i4 e+ j" A; O{
& Y# [2 _7 _0 o6 U9 A' m switch(m)/ u1 m& {% x/ @; L3 S
{- F6 j1 ]7 S3 j4 s, r
//人带羊过河
6 L0 k6 o5 r$ @# v! G% A case 1: , k/ l' c) j7 a3 F4 |
//判断人羊是否在同岸. X0 v2 ?/ M3 Q& U8 S- J
if(s[top].man!=s[top].sheep) + w' {: \( {5 R4 d8 R
return 0;4 ~/ |! [; J; _0 \8 x: b1 ^% r
s[top].sheep=s[top].man=(s[top].man==1)?0:1;% i8 y# S( H5 {
s[top].m=m;//存储过河方法7 A& H" }0 v! P9 P
break;
0 n n) D( c4 a2 `0 u- U+ }* O) r% v0 \ case 2:
9 g' O- H3 N3 {: h B! t6 | if(s[top].man!=s[top].wolf)/ w! M$ e$ a; }( K! m y
return 0;
* C. ]& q/ C9 X/ E/ V1 C! c s[top].wolf=s[top].man=(s[top].man==1)?0:1;. I1 f6 Q! [; R7 |; r; Y4 ]
s[top].m=m;//存储过河方法# @3 U2 H0 z) t8 B3 D
break;- i6 A4 m. R: [! b" _( Z- I* {
case 3:) s9 r0 @9 x2 b4 }/ ^0 r
if(s[top].man!=s[top].cabbage)
2 W3 `. x. U' r, Z" o9 D return 0;5 d y: b* t% L2 A8 s
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;! T& k) w8 D3 B6 L) P& k
s[top].m=m;//存储过河方法" v5 J* [; k& R; x
break;7 h4 {7 L" w- m- S
//人单独过河
3 g/ P2 a' w8 _/ b case 4:9 \( g6 ] S0 [( h2 f- S
s[top].man=(s[top].man==1)?0:1;( l# s5 i# H. w) Q" n! r! k
s[top].m=m;//存储过河方法- ]+ u- ?/ V! N6 K* ^- m( s
break;) E2 j4 O5 R4 c! u' U }
}//switch6 p% O j" W" V
return 1;( V. {! w2 a. F5 C8 n" E
}//move, Z6 Y1 b$ B% X d0 k5 I
//打印过河步骤5 `6 i- p$ t1 o2 V
void display(int top)1 U. Y* l3 R$ o5 [3 G* R
{
: v9 B j" V5 G) Y+ N, T int i=0;# K2 d7 t, H6 Y @4 ~1 @
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);" K4 r1 v% _ o2 I
for(i=1;i<=top;i++)
- k" {2 c! z/ G/ R9 _ {
0 u4 q/ k- Q a( _5 N+ s switch(s.m)
9 W; f5 a) A( k0 M6 M5 q6 x4 _% c {
: k$ S6 _2 G) Y ^( n; c case 1:% _" v3 S" @, q! k
if(s.man==1&&s[i-1].man==0). P& ^) B! r: R( r! P9 ^" t
fprintf(fp,"人带羊从起始岸过河到目的岸\n");4 H: u' `; i& T9 W. t! t- C
else
2 {+ m# R$ Y8 Y6 L, {) \! f fprintf(fp,"人带羊从目的岸过河到起始岸\n");
$ R/ c: w% j3 t6 k3 \1 R break;
; ?2 H& G4 t D# z& E case 2:3 r! ]% f) ~* M
if(s.man==1&&s[i-1].man==0)- j3 Y- G+ ~7 V9 E2 q0 r) o- g
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
" u: m$ u3 ^) X9 t* A4 m& H; W else
9 m; T4 a! y( K! C* c- S fprintf(fp,"人带狼从目的岸过河到起始岸\n");0 D8 T5 D6 { d0 Q, Z9 S1 B
break;2 g5 u5 U/ e1 D0 }
case 3:
- Q. }- n' r$ c o! m0 o/ F if(s.man==1&&s[i-1].man==0)
9 ]' e6 F; |$ c fprintf(fp,"人带菜从起始岸过河到目的岸\n");
$ y' m0 n' L- a, G else/ A8 r# N* _/ {& ~; q. t
fprintf(fp,"人带菜从目的岸过河到起始岸\n");5 P" \0 B' A+ }/ Z
break;
0 H# V. L% ^) _1 w3 t3 Q. l case 4:" \" x. J1 ]9 @1 x/ E; v2 e
if(s.man==1&&s[i-1].man==0)+ q1 _1 K; H; Q( K* Z" \
fprintf(fp,"人单独从起始岸过河到目的岸\n"); v& _" ~: m' H
else" N1 j% I0 [, u; f' A) L
fprintf(fp,"人单独从目的岸过河到起始岸\n");
+ p+ l; q+ T8 w break;
4 r a( {( {$ ] h5 X }//switch
) j( x" `0 B: E" {7 k0 p fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
+ G2 U7 \4 k6 w# _ : h' W8 k* P9 K' q0 ~
}//for" B8 y9 c z3 L+ m% z& U) o+ b4 a- I# E
fprintf(fp,"All ferried successfully!\n");
! X/ F6 c$ V0 O3 }. c9 u/ a6 O}//display
1 f' ^9 C: ]# }6 K7 u//检查两岸合法性已经有无状态与历史重复性$ w$ a0 n1 D1 d6 b3 K8 r2 {
int check(int top)
4 `/ a" ` n- W, I1 [# _6 _{
. e! X \) w! T6 Y; v int i;1 X5 v# b% E& c# H8 c# s
//检查两岸合法性) h0 |& P/ N5 U% `. O. \
if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
2 E8 D0 H6 h( x! ^- n (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))& n# Q" M& z# o
return 0;
. d% K! D# x- d/ J5 x //检查历史重复性
- i, {* Y$ f7 _: `, q9 s for(i=0;i<top;i++); l% a9 f9 ^( {7 Q9 F; ]8 S
if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)0 b4 w7 ]8 C: h! v; v4 D& y2 f
return 0;
$ D, l+ [4 L0 d' R' x# h% V3 ` //ok# E- D- s% x" j4 C% c* J. |8 r
return 1;6 n, y5 E# Z: E
}6 {1 W2 J& \6 H5 Q3 p9 E% D$ D) M; ?
void f1(int top)
; g- k" J) G- S" o% ]{
9 F0 F! ~* z- I( s3 D int m; a% p3 j. ]3 o+ X
if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1
3 \* j" z9 H! k5 w { //对每次状态分别试探4中方案) w* U) _; o7 U. N
for(m=1;m<5;m++)( D3 w$ ?7 H) s* U0 M' @
{
$ Q# ]. I+ X0 P3 Y0 \3 u" M8 [0 S. u9 x //每次方案的实施是在上次结果状态上做的
2 J" d' Y* m% z0 P# a s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
$ z8 y$ I4 t/ y; v a* d+ X: j s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;' O& m' i2 k& a1 Y# S( m
//用方案m移动,同时检查结果& }3 v6 w4 U9 \3 n; A* b
if(move(top,m)&&check(top))
+ ]% M( J8 O- [ B1 X {2 U# A2 ]8 `7 b) O, t
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
" `- D! p! m+ n- _ {( t% ^/ j9 A4 W* U U. a* ^' n+ z
//打印渡河步骤
" a! t, r0 x7 o9 Q( m' h; d display(top);
7 B# e( r( g9 ^ //统计方案个数
0 V6 N& J5 J/ s9 L l0 g0 V* o count++;
) D6 c8 O6 m: U( g, q fprintf(fp,"count=%d----------------------------\n\n",count);2 M+ l9 `# v8 r4 K P
if(count>1000) exit(1);
9 b' Z& V! e* ~' F, L }! @8 n2 m, A; p- j
else
4 r6 Y* d2 }( c3 e# P) n f1(top+1);
2 ?1 i$ W1 ~7 W: j }
1 V; q! H U9 v) l6 {. `/ ]: a3 W& v7 S }//for g7 X5 h% x* `8 p* N4 V
}//if(top>=0)
# \, R8 {3 N. o: g& ~2 L d8 M}//f1 7 O/ b( A9 `7 F) k
8 U: ~' L, ~* G* d8 s$ }- |
( a1 b! u& Y8 ]# V' _
' Z0 u& D. @3 F5 z! X# J' D3 P' A7 _void f2()
; w2 n, _# E5 C+ }5 m5 h( A{
6 w5 a) ^3 V2 n8 u+ R/ ^+ U& D) g int top=0,i;. b+ a: H" B6 `* x( {/ z
//开始时都在起始岸
3 v' T' Z4 O a& b0 c s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;" @* K- Q. H+ {) ~1 c# |
//未开始渡河
7 p0 h7 t: t" X+ L0 }5 v! z s[top].m=4;, z( ~2 W6 o) s- H, p1 \
while(top>=0)6 @9 C2 L4 o% G/ R! i9 T9 ?
{
( b$ y4 G. @/ J/ I7 A' H7 L if(check(top))
5 D8 }% r* I! M- c9 e/ S {
9 z5 G5 P- o& O6 Q& q8 q if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
1 T+ L. t T3 |2 M {% ~% V; r: A, ^" V- N+ L/ Q
//打印渡河步骤( N9 V# I: ?9 c8 {+ [, P
display(top);2 V7 H5 ~0 y/ f. {! S/ A7 O+ v/ h' s
//统计方案个数
5 `) ^7 O: D. O0 Q W count++; 7 _# {6 B, J& |) e# t/ ` m2 J+ [. v
fprintf(fp,"count=%d----------------------------\n\n",count);6 [8 C+ K- V# C0 x4 J7 j, `
if(count>1000) exit(1);3 ^0 w. g2 Y1 a% u( q! {9 d# i& ]
//回溯- \/ B. m5 K6 q' N/ C" C4 `# o
while(top>=0&&s[top].m>=4)
" D5 M4 q2 r+ k+ c+ |$ { top--;
: j0 V7 D5 W$ K3 \8 c. p7 R if(top>=0)0 \( d4 j9 |! F, D
{8 y/ c, E5 O2 |8 O* F& C# M. h
//在上次状态基础上准备做move6 P2 {/ y6 a6 x6 [+ F
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
+ h* @8 \. y& ? s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
7 h2 e; _* m3 i* q& ` i=1;1 q9 m+ R t# M
while(s[top].m+i<5&&!move(top,s[top].m+i))
) `$ O" r' H" C5 M7 { i++;6 n, W% Q, I7 v# @, C3 K7 @
}
6 q: G& h& u4 O6 r3 X% m }
* }7 t, K" V1 `: q& U7 [' Q else& S' v8 C }# _' u* w1 D7 A# p
{
) n! H; E' y$ H. ` top++;
1 Y" c6 D7 l) d/ }+ F //在上次状态基础上准备做move
; [* Y- D1 k+ {% I$ B s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;1 L2 \8 J- F: B) `5 _/ y
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;' G2 }: B$ t- {2 U- u I5 q( L6 D: E
i=1;& O9 G: {# m5 S% K8 \( Z+ B. ?
while(i<5&&!move(top,i))6 l! Q5 a) S( \
i++;3 b& H: W% R- {8 H! d; ` H5 R
} / M, f7 n& ?" Q+ x
}3 g* C( d& u j/ O
else
. J3 O! T( J9 o# A% E3 H {% ~, I& s0 Z8 i: r* W4 h2 @
//回溯( D, k0 s9 C2 F# s0 J+ d
while(top>=0&&s[top].m>=4) 6 u1 T, I: K8 a) \
top--;
% A" j, j) a5 k' p- P7 q$ ^( j9 n if(top>=0)
4 i4 _8 p: d. S" v) M9 _/ G {
' _$ W' X5 x0 N! h& M3 U2 m, b //在上次状态基础上准备做move. ?& E1 Z5 K7 K" p# N4 {
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
: X& P# |+ \& w0 n; ^+ ?4 U s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
8 ~9 q! Z+ H3 k+ A) S& y i=1; " v3 C9 N5 H- d- u3 f7 |
while(!move(top,s[top].m+i))
5 Z$ o) }0 m9 M0 `( E2 J i++;2 w# v% d& f. `+ l+ I6 ~
}
7 g4 t$ U) W% ~( X- _# {3 h }/ H! l8 @6 n5 O7 a1 M j) z7 B Q
}//while
- }' S! s3 j" M& m* p}//f25 r$ I% e3 L+ G: U/ `
//---------------------------------" t: k5 i8 U' y4 P) X" U
|