|
渡河问题
. E* Y W- E6 m! L* e 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?
6 V4 m' T0 c4 F" X
# `( x$ \9 e2 G3 s2 D程序代码:
7 I R3 X. i" }, D& M//以下程序在Win98+vc6.0运行通过 5 q9 B7 h8 j3 H, t; q
#include <stdio.h>
# y) s- D& o8 A4 u8 A( s. L8 y0 d9 A#include <stdlib.h>9 y5 c3 g- n& R
#define MAX 50- Z2 p7 I3 t- C' X, L! t% }
struct state
: ~4 ]# j v$ T4 [4 S2 o. ~( |{ j1 ]& d+ l+ M: X
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸, Z6 V* `# k6 v4 R
int m;//所采取的过河方法,(1--4)3 }" D9 y" l- @& ~: F$ o
}s[MAX];2 Q8 F( c4 V6 P' Q
int count=0;6 c. a0 y. U7 I0 U N/ p7 C6 f% [, J
FILE *fp=fopen("c:\\2.txt","w+");
- G) D; p" @. g1 I7 M' d8 n Tvoid main()
: I# @7 z& S8 O{
9 X: X' i- Y9 |4 q) {. ~1 f4 G void f1(int ),f2();//f1试探递归- V% G) N! q! [& G
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
4 P {2 u" J$ A; M, \ s[0].m=4;
( o1 J' t3 ` ^; J) Q s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;* k6 J- d0 f* U/ X$ s' b
f1(1);- v& J" [. H5 ?: b0 j
//f2();, Q; A2 ]- L) \" Q
fclose(fp); r* l! u! C; b7 i$ H, C% j
printf("\n"); 9 R& j) s$ {% @! {+ t% r
}6 W- C9 z, t' z v2 U9 k4 y
//用m值决定的方法渡河,成功返回1,否则返回0# E- x5 G. a w! U3 @. z
int move(int top,int m)8 x6 {4 T0 u1 P0 s$ c6 M
{" J2 X1 t' F) x/ i; H* {) ]
switch(m)/ G7 ]& s7 T& K: W2 M _
{
( t5 C) j) C, t% f T //人带羊过河$ c/ b' [ V, g6 q' \
case 1:
0 b' U/ ^5 O* [0 Q1 A //判断人羊是否在同岸, P2 a; g) s& X- I! W' L1 ^$ Z
if(s[top].man!=s[top].sheep)
6 X6 B# Z$ ~' Y( L& Q {3 e return 0;1 [3 l( o% F; W3 w* E; n
s[top].sheep=s[top].man=(s[top].man==1)?0:1;
- N, O7 c+ W& n. i% T s[top].m=m;//存储过河方法8 O5 i% n6 i S5 x# L
break;
3 q, y' O3 M. \. [ case 2:' W; m+ y" W- z; _9 q+ _
if(s[top].man!=s[top].wolf)7 y/ C I" V$ J9 F
return 0;3 g- ?+ e ] @1 ~) w
s[top].wolf=s[top].man=(s[top].man==1)?0:1;: P, _/ V4 g$ s1 h3 C" j3 y/ U
s[top].m=m;//存储过河方法# j$ _8 [0 ~# V7 @, M; s: @2 x) w, V
break;5 h: q8 ]% _9 ]6 e: t' h
case 3:' X' d/ R T5 l" F4 Q: \ s
if(s[top].man!=s[top].cabbage)7 p* t# j3 o! q' I
return 0;
, ~$ o- e, m8 ~5 ]. g( n s[top].cabbage=s[top].man=(s[top].man==1)?0:1;8 F0 Q1 j( h2 ^; a6 P0 E
s[top].m=m;//存储过河方法9 J0 P3 y# U3 @$ G
break;
& U- ]7 |& {+ x //人单独过河
/ ` S: H' i2 @$ b, z. } case 4:
6 X+ w( {* A4 n8 {' W s[top].man=(s[top].man==1)?0:1;
( [/ ~6 Z0 r7 x |# b3 H s[top].m=m;//存储过河方法% s: N" R/ ?8 b
break;8 Q- L1 R( c3 h
}//switch" z, h. _) K% J8 a$ `
return 1;
; i; a: T8 ~5 {8 F4 T. D* b/ d}//move* k, o: L6 f2 x/ `( `6 k& X7 r
//打印过河步骤7 X# l- c: n7 j8 }* h2 ?
void display(int top)4 ?( M7 k) w( z& d* h9 f
{7 W5 }. G, K+ \) w, k0 ^. ]) o
int i=0;0 ~8 h! A ~8 r/ s
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
8 s6 P1 v3 m% R" n, r y- H for(i=1;i<=top;i++)
3 D1 m2 `8 H* z9 M) j# t {; W4 n+ E f1 o/ h$ s
switch(s.m)# x, C3 n+ S4 u) m" s e
{
! x; L6 D( U! q case 1:
+ J/ T4 e3 {' l5 L" q' {( B- x if(s.man==1&&s[i-1].man==0)
; m, m6 \& z$ o* q2 D fprintf(fp,"人带羊从起始岸过河到目的岸\n");
7 D2 [6 u& q" p7 M/ N1 U! r else4 g1 g! l6 b% v- m" M0 o1 m7 {
fprintf(fp,"人带羊从目的岸过河到起始岸\n");
8 y$ j. I' L0 J, s5 I5 A$ q. a break;; i7 ~: A" [1 F9 p- u% @$ n" O
case 2:
7 p2 w: {- z+ _& n E1 U if(s.man==1&&s[i-1].man==0)' p( { E% N1 R6 W9 u) t5 Y
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
- Z8 C0 T; S! j' C$ h4 i else' t. a) z) Z" `
fprintf(fp,"人带狼从目的岸过河到起始岸\n");
6 a' P* D% ] a- `) @: w7 s break;" e1 h/ f- X3 N+ v; C6 p* s3 p7 e
case 3:
. n6 G; T7 A1 \ if(s.man==1&&s[i-1].man==0); r" |$ G0 s3 I" T7 |4 L$ B, W
fprintf(fp,"人带菜从起始岸过河到目的岸\n");
+ d% C- K7 Q7 ~, l else+ j% b# J& h3 C# t7 H
fprintf(fp,"人带菜从目的岸过河到起始岸\n");, e& n, s) l- ~0 j
break;3 B; V$ W4 Y* m6 t- M
case 4: p1 b* [; l% f* } V" `/ o" L
if(s.man==1&&s[i-1].man==0)3 [8 I0 `+ t) S& m8 K
fprintf(fp,"人单独从起始岸过河到目的岸\n");. ~ \- M6 Q0 O# N5 V4 r1 b+ q8 `' w
else
1 L! G% P* `9 O5 |7 M. H fprintf(fp,"人单独从目的岸过河到起始岸\n");
$ C1 ]! |+ ~. T- |0 T5 ?. R break;
! v% G9 w$ b8 P8 r# _! p' P }//switch! S" _7 x8 K9 h- x, e
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);# b; u. Q X4 S4 i
% V; Y1 X# k* o
}//for
4 M5 z1 }1 s! ofprintf(fp,"All ferried successfully!\n");0 m( G Z. x" W2 U P) N5 L
}//display
5 N9 _6 p! n3 _4 n5 t2 z6 {1 t! P# F//检查两岸合法性已经有无状态与历史重复性
. q& p1 c/ ?. n; l) t) n& K; qint check(int top)! u3 Y. P% ~0 M, \
{
$ ~3 [, e1 \* ]' s. q5 s int i;- S% ], i) _* Z: Y* Q. a! E
//检查两岸合法性- t- M7 E2 a: g) b/ y
if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
5 V4 \$ m& c+ K$ ^: G0 ^# I3 P3 h (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))4 S! g* T) g5 [( v- O4 |( q" T3 ?
return 0;" w! Q; T, C% p
//检查历史重复性
6 Z/ f/ g) a: A2 z for(i=0;i<top;i++)
( D) ~7 d+ e+ `- w% P if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)( v+ A( j7 G+ ^, [4 x* o
return 0;
D: W% b7 [+ ~0 H9 ]9 S0 ]1 ] //ok# U6 V# b* h* w6 o( t, E
return 1;
5 j5 _5 t% p* P( _4 S}
2 ]) Y# x0 P4 ]' kvoid f1(int top)
! _" N6 q4 d# C: K1 `2 ~{! o! a. j9 f' R
int m;
$ [, ~# g; t' W9 Z- [ if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是12 T% X6 d- P0 q6 {
{ //对每次状态分别试探4中方案8 ^" r. }. B0 a& n4 a
for(m=1;m<5;m++)
2 g! x5 c9 T# x0 Q$ ^8 d2 a {7 I$ T7 g+ K: L* g
//每次方案的实施是在上次结果状态上做的9 k% c" N( ^- _# d$ U
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;7 N3 r3 }' m* y2 ], w
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;' V, |& @+ V$ c1 @% P
//用方案m移动,同时检查结果0 J) V& [8 ~2 {- ~$ L4 w
if(move(top,m)&&check(top))& V/ n& x( y4 ]: j4 Z4 n$ O
{
/ j8 U- L, g1 } if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
2 a: c* \8 G( D+ H% M' W {
; N+ I9 I" h: [+ d! p //打印渡河步骤
( u5 T# k' i9 q+ C6 W, U, I display(top);7 E6 X1 j/ u$ |0 Q" j$ w/ x
//统计方案个数
W) @0 C- v9 c3 ~3 P count++; # ^. a; u" k* c. f% T; h
fprintf(fp,"count=%d----------------------------\n\n",count);
" D4 F C) q1 c0 l1 R+ W2 k# _4 s- x ` if(count>1000) exit(1);, c' j- ~; T1 l5 m' U) o' i( _
}1 @2 r. H9 q$ A/ w# n
else
5 A& o4 x. I: N$ D! ]$ ?# r f1(top+1);
, J' ?4 H! f# r) h# E! H3 u }0 ^+ P4 d5 ^9 T+ `1 i, Q! G
}//for
& Q, Q! Z3 l, h* j+ Y1 C& V" ~ }//if(top>=0)% [! ~7 U1 A9 W9 M8 D( w
}//f1
+ ~7 `0 t; u1 Y4 y+ e9 q
8 A$ y2 _' b; f0 W! A
3 i! H3 s. n4 {. S! |, v
+ [! S' }$ D) ?void f2()
6 f$ {+ r+ e: O# }7 j7 d# p{7 B l; A& N; f4 |! N
int top=0,i;$ g6 H- @& Z1 ~
//开始时都在起始岸- z( K: a, T, d0 ~* r y" L
s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;' l8 `2 K7 @. H
//未开始渡河
$ `, i0 r6 v7 c$ s" P8 L5 g" O/ p% ` s[top].m=4;0 S# U+ ]' Z; d5 ]0 O
while(top>=0)
7 |4 | {. {- j5 R6 T {8 M/ R/ [: o* \1 N1 u# Y3 h* E
if(check(top))3 i+ ] s+ C. p" d
{
* Y9 P! U1 K! L6 n% V" f" w$ o+ S if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ), X; g: [6 x! _/ a
{
+ ?; q- u5 B2 \ //打印渡河步骤, `4 m, M8 Z9 K* ?
display(top);' c; l; x# q# `: {9 U e
//统计方案个数1 h9 h" C5 l" U& P' k1 `/ Q
count++;
" }* R: t* {+ A& H0 ^' z5 c fprintf(fp,"count=%d----------------------------\n\n",count);
8 ~0 A1 Q( H: \( q$ b if(count>1000) exit(1);
" F7 z6 o/ ?# F! b //回溯/ f! W0 E6 `$ T; n* \
while(top>=0&&s[top].m>=4) $ Q4 y( z' G# o% \4 e% _
top--;; g# A% `( r+ ^9 O& e$ ~
if(top>=0)
A2 {4 a, {# Y+ g {9 h V, O" Y* V1 r, I
//在上次状态基础上准备做move+ P+ U( j2 k5 ]/ t9 W3 ?3 [
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
! K* j* I) ~: L3 i; S5 |3 j s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;; \# ~; V6 X0 ?% G" h
i=1;
4 c! ~- k' @6 E+ q3 G while(s[top].m+i<5&&!move(top,s[top].m+i))! t2 ^6 t6 Q) `: b/ @8 K3 Q+ e- H
i++;
- M' b) L6 K# f) X7 J } ; I0 N! X I5 [$ V
}7 {1 A" ^" |0 m& }' V
else- e c9 n3 y/ C* n* v9 p; \) \
{; V# B" N( }( P# G" z
top++;+ i- U& F: f1 p' K
//在上次状态基础上准备做move
: ?% c, }. A* w5 t s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
1 T/ P1 w3 Q9 [' R# w, G s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
7 @3 w* N7 t) Z& }9 T i=1;# k s; m& e# a6 }/ {$ H
while(i<5&&!move(top,i))- C8 T6 t9 d4 w. i {6 r
i++;& Y$ X( u( |$ z) D5 o7 [# r: w
} & ^8 k: \, ?$ B' F; k
}+ ~3 `& T+ P! m, f
else5 l& @0 l# ~" W1 O: t) l
{2 z$ D, c A9 U" A! e) P
//回溯
* E: j" ?$ W! i% g while(top>=0&&s[top].m>=4)
+ ]6 s* s% i3 f5 s" L. e& R top--;
4 F( B( o$ O# t( w7 f. \+ r' L+ Y if(top>=0)$ r! O/ n! o$ H/ N1 A9 k# |
{
, f1 X: j$ I. K //在上次状态基础上准备做move
) W, x' _3 M* `# V Z& I- X s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
, P1 G% U: R, n, |0 i3 D s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;4 f4 q7 a* T* A7 o/ \. f
i=1;
2 m* O2 C" s0 b9 e8 y while(!move(top,s[top].m+i)) B) H+ f: w$ J
i++;! S3 Y/ w/ l( B$ E7 \. h
}, m* V. h1 F7 m! k
}
: z9 D7 a# `) A+ v- T" E' R9 g( M& B- z }//while/ h6 \: X, E0 K' @3 e
}//f2
2 F8 P4 k! s4 T& Z' a: x//---------------------------------
9 a2 D2 U7 _" G3 j0 b# h |