|
渡河问题 % V0 A5 x1 ?# K3 E+ n" q8 _
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? ; o" j+ u( k7 ~2 Z) ^
' v, x+ d; K3 `4 ?, L; E程序代码: 8 S: {- u0 t' c) H1 B
//以下程序在Win98+vc6.0运行通过 + G. X _6 l/ x1 P
#include <stdio.h>6 n% u$ P8 d) d& H. [! y
#include <stdlib.h>
# j5 ~ Y/ n O9 z9 J! ?#define MAX 50
: O+ Y0 h2 R( Y7 L; [, a, P B; lstruct state/ h5 q1 `: \7 |: f9 o9 f
{2 g& W0 H9 L) Z% V; ~5 s) q! |2 i, m
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸
* N3 U1 T+ d5 J int m;//所采取的过河方法,(1--4)
% P; u6 @. _9 G) e5 `}s[MAX];
; i8 i) P' B2 x1 A) uint count=0;, F- l$ h6 E9 E+ d( N7 D: r% l* z9 B
FILE *fp=fopen("c:\\2.txt","w+");
, N+ i* K9 h' j7 b" U( m$ H8 e( Avoid main()
8 w$ R5 e! z. d& I7 T+ s! ^2 I* i{
) k9 y( C6 ?' \/ C8 ` void f1(int ),f2();//f1试探递归
' v( a9 H. {/ B( W3 W( d+ Y s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
. ^8 H3 e4 }( U( b7 F9 H% {$ W* z s[0].m=4;
7 m) g) |7 o( e o3 ^3 o+ W5 ~5 D s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;
0 _ e! I" w1 u* {0 T8 w8 _' f8 a/ T f1(1);9 [1 j0 v7 X. s" d, s8 c
//f2();
. X: D; C. s0 ?2 F* M/ j fclose(fp);, @# F) T0 Q. M0 g0 d) n
printf("\n"); $ `) X N% \) I3 e
}
! v! u# d, I" f9 }% m) m0 B* M4 M//用m值决定的方法渡河,成功返回1,否则返回0
8 c: h7 V! X3 f9 ~8 f dint move(int top,int m)
5 |9 S8 k' x1 U$ x* n* m/ k8 x{" n4 X) c7 B& [; z! A% }3 x
switch(m)
: k) N$ E' m# N# L5 k5 w {7 S. G5 Q# r" S
//人带羊过河% b+ M& s4 _" f8 x2 [" Y" `
case 1: / @ H) Q3 I: O& K
//判断人羊是否在同岸
2 K- Z6 ]0 h w4 K% Y, X3 b if(s[top].man!=s[top].sheep) 3 J8 k0 S! a; U1 m4 ^
return 0;4 i& w) p- {3 {- m/ \, |
s[top].sheep=s[top].man=(s[top].man==1)?0:1;
# t j& V# C- C4 G* n4 m6 f s[top].m=m;//存储过河方法: I3 j1 r; |% @2 W6 a" n5 M
break;% n4 V3 r6 y/ o; f0 F
case 2:
* }% i }* O0 |4 h% c- w; _& q if(s[top].man!=s[top].wolf)
7 J I* V; Z* E9 O5 P return 0;$ A% a2 m3 M1 ]* {
s[top].wolf=s[top].man=(s[top].man==1)?0:1;
$ X! L4 A7 ~/ q* p- y s[top].m=m;//存储过河方法0 g$ Q( ^8 T) X. _/ w% F- j
break;, t" [! j6 p7 {9 r
case 3:
7 S2 w% R. d9 s" w if(s[top].man!=s[top].cabbage)
6 o/ n$ \1 _5 F* t/ H return 0;: h6 l3 m3 \. i0 `- k2 S
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;4 G2 l" ~+ F! P$ D. l% _3 I
s[top].m=m;//存储过河方法7 N9 k) \ B+ b9 l' O z% Q8 ~
break;
' K, {. W8 R0 ]3 s& e0 Z% h9 C6 g //人单独过河
: \+ P i. V M case 4:: d. g& i. S; R/ X
s[top].man=(s[top].man==1)?0:1;$ p" t- M8 W ]) F0 U
s[top].m=m;//存储过河方法8 B! }$ @+ r! k' |0 v/ v1 f/ W
break;
: ]! m9 V' w0 S }//switch
0 [4 x& p8 H! Z5 s) g: \3 ?: ~ return 1;9 ]" r- O' S7 f8 Y" Z
}//move- g/ Y5 s6 [7 h1 C2 ~2 D# X4 T
//打印过河步骤4 T) M5 H4 C% F! K
void display(int top)% t9 A3 [8 c1 Y2 _# G
{/ b" e$ }5 o' G6 R3 _* |0 C
int i=0;7 D9 ?1 g2 s' [# J( I- j
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
* [# `" ^7 A. r: }8 s for(i=1;i<=top;i++)0 I6 Z% Z9 Y. L+ \( R# Z
{& _2 G( Q2 j) f; d: Z+ x
switch(s.m)& ^3 C" C! a# Y8 i+ n% M8 I
{
+ q) O Z+ y% q' o case 1:
. O% G' E. v1 y! H3 ?& X9 E if(s.man==1&&s[i-1].man==0)/ j# ] C4 b2 o& O f4 d
fprintf(fp,"人带羊从起始岸过河到目的岸\n");
9 w. z7 }! q' |" d; c, {3 ? else T) k! W( {! z; |" z0 l% a
fprintf(fp,"人带羊从目的岸过河到起始岸\n");; m( t* p- ]7 c8 S% ]
break;
. L+ e0 C: D( | ]" e7 k9 Q case 2:! w/ X9 b( S$ X
if(s.man==1&&s[i-1].man==0)
/ b( ^/ m- _, V fprintf(fp,"人带狼从起始岸过河到目的岸\n");
3 L4 _# u$ t+ z* Y else) B: q6 k5 V6 I, j1 l+ @9 m
fprintf(fp,"人带狼从目的岸过河到起始岸\n");
) I$ D* h) Y) [7 t- k break;
. V% ~2 z, Q. ^0 R3 S% ] case 3:4 v& [5 s( t+ D: ^5 u; E" [1 i
if(s.man==1&&s[i-1].man==0)
! i5 F' ~& @/ h5 l% I( X6 f fprintf(fp,"人带菜从起始岸过河到目的岸\n");# p$ x. p/ u& }3 L7 |6 e& V u0 T
else8 w% ?2 T# p1 v/ F0 D
fprintf(fp,"人带菜从目的岸过河到起始岸\n");
, _0 X1 X- n: \ }% \* i break;
( {/ D# G* X& [3 [7 @7 T% v3 u8 S% O) H case 4:
1 S$ B7 |7 |7 A) n% F( t if(s.man==1&&s[i-1].man==0)
4 q' {6 {5 i1 o fprintf(fp,"人单独从起始岸过河到目的岸\n");: E! l$ V6 [, x4 j
else) V/ D6 k7 B$ ?. m- }+ w) d
fprintf(fp,"人单独从目的岸过河到起始岸\n");! j! | O9 a+ g0 `9 K1 H2 e
break;7 Y( e- k: ~# U6 l
}//switch
% F/ L6 c. }& T! F fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);$ V7 X5 n/ |( P* j% u- B! P
; i2 t, P9 l7 {5 d: s }//for
/ ]/ U, \- s v) y3 `8 R6 Gfprintf(fp,"All ferried successfully!\n");
3 W0 d: P7 I* P}//display
+ P5 _$ w& W$ Q. {: j//检查两岸合法性已经有无状态与历史重复性8 `( w( V* ?. _2 q" }6 U& D
int check(int top)
9 K2 Q" T0 y6 x/ ^% b( D{' g8 S7 z6 x' L+ F# ~3 `
int i;
' n( ?8 | a, O4 e) o//检查两岸合法性
/ H6 d* E/ g+ @& @& R! g if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||" u; O5 V! d( ?. u! F0 i0 r: G
(s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))
/ d! a! Q" H. u' R6 s return 0;" L: P0 F+ K* O9 A/ T$ m& k7 t6 B7 ~
//检查历史重复性
: b8 n8 l6 V. _5 u" _7 X/ q for(i=0;i<top;i++)# K" x2 T0 z) x* m% d- r
if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)# ?" V: @, q0 W" T' H) f3 n7 k0 \
return 0;
. n5 X- k+ ~8 |4 Y //ok
) M. E# s5 O, i4 u# B3 u! Y return 1;3 Z" j9 D. f% D7 f
}3 z3 X- S# U5 c
void f1(int top)' C% r8 @: J3 q# n9 g( S: o
{) N% X, d Y- C# P0 e
int m;7 t2 Q7 e/ z9 d& n5 l t2 L. }
if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1
, \( X3 B5 r! D+ \) v1 l { //对每次状态分别试探4中方案
0 U2 f$ n: a. S for(m=1;m<5;m++)
2 ?( r% e! ^$ J- p. r m- t4 a2 J$ u& p {
4 X' y- m P. `& ?: f& I8 ]5 S) O //每次方案的实施是在上次结果状态上做的
9 L! C* [( U0 ?3 d7 i6 y s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;$ \6 o) _% B. ]0 z8 _9 r5 _! q4 B
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
3 x% A1 N) P. I3 c& }, v //用方案m移动,同时检查结果
, \2 Q4 U: g& N4 W) o/ Y- V( Q if(move(top,m)&&check(top))5 C) |8 @# ~* c
{
& V. Z2 P3 b# E1 d+ j; V if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
3 h0 _; K1 g6 r( P {0 b" K5 `% R! j5 _& h" d/ F
//打印渡河步骤
& \9 @7 S: t# S" k) m: ]( @ display(top);* j3 s: G- r4 ]0 _1 l
//统计方案个数7 V$ \& x. f" b# a8 ?" a* ?
count++; ; t2 q$ o& U6 T- X/ {( A
fprintf(fp,"count=%d----------------------------\n\n",count);
+ b8 L- @* D I3 F2 T' D i if(count>1000) exit(1);
) N% T S/ v" f1 I }
) Z- G# D+ w1 h else; B2 f3 U" [9 n, Y* D J
f1(top+1);6 `0 ^5 |* u3 V) P/ B
}0 O8 y5 a; N. r$ b! C0 d ]
}//for7 |2 b# s6 }6 {7 }) ?! }
}//if(top>=0)8 b' m) C I9 m, G9 u/ N4 b
}//f1
' @$ k! y8 X! S+ Y# c9 x+ h1 ]" K) N K) ~8 q) B1 X3 Y. N! c
4 o2 \' S0 h( D5 r9 I# R# c
* K# W7 Y r* k0 N5 r6 W: \: yvoid f2()
9 v1 `+ x1 V- L) G9 g$ d+ v ^4 J{3 f! @ ^0 z! F! g5 D# F4 f2 V
int top=0,i;4 c$ N/ ~9 K6 K: u& b8 d7 z3 W
//开始时都在起始岸
# r9 y. o) i# t7 K+ e) A s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;+ Z/ o, p/ P5 y
//未开始渡河
' K0 s: c) k/ \' Y. ?2 }' v/ z s[top].m=4;+ |/ G; `# x( i
while(top>=0)
" u5 ^ m) e* K4 ~ {9 K" S/ ~2 w# F6 | F& N s6 ^
if(check(top))/ Y$ I' ?+ t. Z$ k
{/ k3 p( S$ n- X% m. _: B# |0 j5 S
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
9 D* v" }+ B; w {
) |; s I/ z. w //打印渡河步骤
# A8 {) r4 Y9 D1 N display(top);
2 C" `! O$ p2 }: Q0 g. a% ^) z/ p5 r //统计方案个数* g! f6 G& U( }. x( j$ Q
count++;
6 L l2 k$ E- ? fprintf(fp,"count=%d----------------------------\n\n",count);( t( j/ m& M9 v, q+ R1 W' Q; u
if(count>1000) exit(1);
1 i9 X- G( W/ B' } //回溯6 c: J8 h( K& E1 g6 a/ `
while(top>=0&&s[top].m>=4) # t+ X) ?, p+ K# w' q! \
top--;$ _: Q" f& V& R( q
if(top>=0)4 k' o Y" a3 {) Z* }( s$ i
{
# f l. E1 I% c% @8 i3 L! R //在上次状态基础上准备做move T! K1 D$ k# `. J+ L
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
, R4 W, x/ o) K% s s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
! _# \" u5 L; y+ r/ Z8 M i=1;" r; ^8 G. y6 y
while(s[top].m+i<5&&!move(top,s[top].m+i))
( t. J% V5 w" H# H) }( X( e3 \, \- r i++;2 N; S* {9 }$ T( p- `# C! W0 ]
}
6 b: j# L8 ~5 Y! R }
J6 i1 r: K% x0 S9 Z else
4 C/ R" @' D, M5 A {
% v2 ?# Y: M5 A* A" V( w0 n9 D q top++;
. t2 a2 U0 t* W //在上次状态基础上准备做move
6 m; j$ m u4 }1 R' t9 I+ F s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;& T5 @0 w' V( Z. j
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;5 u, h: a$ a' }7 E
i=1; A/ m- J, z r+ o) _+ ~' O
while(i<5&&!move(top,i))
: y( u8 v# r: Z/ y i++;
4 |$ ]! m6 u" a# I5 W2 s3 M } 1 ~4 A) s9 a1 e: \( ^/ t; T8 J
}
* ]6 w0 D* L2 @: Q, J. I$ k else
2 R) j7 Y) w( m8 r& c {% Y# D& p# b7 U- F0 [
//回溯1 s$ R9 Q4 ] W% Y n: L+ `7 X
while(top>=0&&s[top].m>=4) 9 C# g3 n# a7 Y) o5 ]1 M
top--;& D# t) }1 r7 F
if(top>=0): D' a* r, ~9 O7 t# q \' L7 _- g
{- P+ X( r% K0 |- i7 _% n4 k. a
//在上次状态基础上准备做move( R8 F, [7 A1 d. K2 v1 s4 v* c
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;) ?1 R i7 ~, e: K; E/ v8 Y
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;6 k" [& K) m: w) T
i=1; 9 V! z8 j/ S) g% N) l0 F
while(!move(top,s[top].m+i))
7 `* _' W) @+ N7 T7 B+ o! f i++;
3 v2 z* `! O8 T5 g% e }
6 e {+ \0 y! X; z3 ~1 i }
$ D+ L% u1 O8 [ }//while
* j& a' K7 N7 `3 H}//f2! }, V8 B' m- i2 |( J- D% s
//---------------------------------0 N* `$ ^& q# |6 y, V3 Y
|