|
渡河问题 # N0 S9 z+ g4 p: N2 Z: D
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?
; Q" K4 U$ f' o8 y 5 i3 N9 @9 n; ^. i3 |& n
程序代码: * S6 V2 u2 h6 s G2 I
//以下程序在Win98+vc6.0运行通过 * w! `7 D" d3 \' d- r
#include <stdio.h>3 o. \2 z; q, K. M5 s/ Z
#include <stdlib.h>
& e1 c, @# T$ a- F/ Y$ y#define MAX 50
2 ^$ F+ G, a9 f2 T* {struct state# m: Q& Q; \5 @
{3 A8 Y9 w0 l& y V' M0 Y; [2 T
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸! ?& X! C! I/ n9 l3 [
int m;//所采取的过河方法,(1--4)
1 a: z/ l3 _/ u5 R% l}s[MAX];
6 r+ y# `2 s5 L! l& [int count=0;
2 g; s- a p6 EFILE *fp=fopen("c:\\2.txt","w+"); 2 B7 I+ w* B: v! i( e
void main()5 J& t* M* g% E$ ]& k. b
{7 S2 I' }" r. V$ k. W
void f1(int ),f2();//f1试探递归
' T9 N; |& j& E- o$ t s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
1 D% i& m) s9 x2 h% T8 Q s[0].m=4;
6 y$ B! B% T7 f: e s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;4 i5 Z: ^& ~3 [; U
f1(1);/ `% l% k d6 ]' B' H/ m
//f2();
) e" G5 I& x' x" [ fclose(fp);0 ]1 t1 ]2 X; K* W) j, `
printf("\n"); 3 ]& J% W# f8 }1 [, a
}
% y- Y( s- @! E' e//用m值决定的方法渡河,成功返回1,否则返回05 y1 S" x; ]: T- i; J6 o
int move(int top,int m)8 K& y8 G7 N$ ~ O( P" {" d! a& i) ?4 C: T
{7 ^! P3 ]1 ~& c% A5 a+ G
switch(m)
5 l$ A7 e' b5 I4 i {" S0 m: @& s! |4 M* U; F& _: K
//人带羊过河( ?" e# d$ R! U6 i" N8 |
case 1: 4 v8 p$ m4 I7 B$ [
//判断人羊是否在同岸+ T: e$ ]* h% ]2 j9 u' b
if(s[top].man!=s[top].sheep) & t% a% a1 q8 F8 `9 M
return 0;3 X, ~. {) a ]4 ]0 u4 Y
s[top].sheep=s[top].man=(s[top].man==1)?0:1;
7 G5 D) r1 T+ `! L1 E s[top].m=m;//存储过河方法
+ F$ f* L- t& z* n4 d P8 m6 T break;
8 t/ Y& A7 z) F* o case 2:, t# M% H) q3 \, z: E8 O. m9 T" l( r
if(s[top].man!=s[top].wolf)
- r/ x( M' a, A return 0;
7 ]4 U8 {6 V6 y8 n2 s s[top].wolf=s[top].man=(s[top].man==1)?0:1;; K8 N9 Z- w0 c+ K+ i' {/ J
s[top].m=m;//存储过河方法
: | A. e- _6 y) p break;
# L. [& `+ t5 c8 [& U- _0 Y case 3:
& h! U. \& |& Q* @* W, z2 T0 { if(s[top].man!=s[top].cabbage); S& e/ q% U. Q9 z) A
return 0;, C7 B# `8 m1 O% Z u+ m
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;
/ g; `: `( z( Z5 r' g s[top].m=m;//存储过河方法, m3 G8 u P6 r l5 B4 {+ `# S
break;
# `0 |$ V# U- E% n! k //人单独过河
6 G, Y& N, Q* P/ Z& ]# U2 C" r case 4:+ s: @& U+ F' |( O4 V! w9 O
s[top].man=(s[top].man==1)?0:1;
L4 O/ Y" k$ [* W9 B9 D; p s[top].m=m;//存储过河方法' z, I# b7 L, l! {1 i) ?
break; ?9 \& [( s, l* T3 c+ l
}//switch" b8 S8 B: V+ k
return 1;! d1 B- A9 C& t0 l: a
}//move
! |4 | Z3 F3 K$ s% ^- l7 A' F//打印过河步骤
' a1 }! ?' p5 l( s" l! ]void display(int top)- M8 B4 U6 Y7 s3 [% F
{
4 o* C8 K- m U8 Q3 i int i=0;
! }5 |( P( I" p5 t7 K! ~ fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
1 \' s8 Q" y! ]) Z" S* ]( Z* F for(i=1;i<=top;i++)
2 m/ T3 }1 B. V* N5 }5 m) P {
: S# j/ c. g) M) J switch(s.m)
@* W0 E! Y/ z4 Z! J) F7 J/ j {
! Q; }( W5 P8 p, @' d case 1:5 d% Y R; c5 K: P1 |' }3 C
if(s.man==1&&s[i-1].man==0)* @4 ~1 i* U" P0 Y' m6 I
fprintf(fp,"人带羊从起始岸过河到目的岸\n");
! s4 `5 O) A! D" i% a else
- j ]1 r8 _. _! ] fprintf(fp,"人带羊从目的岸过河到起始岸\n");' Q$ a, ?. h M- u
break;
" {1 P: `: l$ x* f case 2:. A$ c- N2 Q8 L
if(s.man==1&&s[i-1].man==0)& x& N4 a4 N# Z# ^; q
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
( h& B0 _, |8 m; ~" x8 o5 Z( j2 w else
5 Q t( y6 S& o5 f s fprintf(fp,"人带狼从目的岸过河到起始岸\n");
! G/ [$ @0 `1 S0 v; U5 A! y break;
, q4 Y, d! y' v$ }8 n Z, _' r case 3:# o" I, T6 [4 Y( V1 T' l* o
if(s.man==1&&s[i-1].man==0)
# e( G: ?: _4 s* T fprintf(fp,"人带菜从起始岸过河到目的岸\n");
! G9 `1 A- A4 |: k5 R+ b, z else& z/ e+ g9 v6 I. V. O
fprintf(fp,"人带菜从目的岸过河到起始岸\n");
! z L) ^# X. V. ?7 } break;! q9 c% F$ l7 a( n6 C
case 4:* N6 u2 j4 W% W3 S5 |. z0 b' w
if(s.man==1&&s[i-1].man==0)
5 j) a U0 Q3 A" f fprintf(fp,"人单独从起始岸过河到目的岸\n");/ Z* a: _' ^% q- D+ P+ y, H
else- B6 s; C8 v \+ N8 _
fprintf(fp,"人单独从目的岸过河到起始岸\n");
- c ^! x$ V7 c) v/ s/ W( c% l- h% T5 { break;
y# q; f% a. s; l" u" }* n }//switch$ {* C; Y4 I q6 f/ Q- o9 {- p
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
. a8 F& W9 m$ p# }# i/ m+ o " j% j& M2 _( S; p( {
}//for
3 I0 |& n2 c& O, Jfprintf(fp,"All ferried successfully!\n");0 l# G" D$ v# W/ w
}//display
8 E3 L; g$ S4 m% |/ |- s//检查两岸合法性已经有无状态与历史重复性
$ ^( @ {4 K% M; P. n' yint check(int top)' T/ y+ @3 P: U, Z
{ k6 u( `4 y# [8 C; s- s$ \
int i;, C" T9 A; l G' s1 o0 y
//检查两岸合法性4 r: C, P+ T. L- G# P
if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
- A+ h# q1 `8 ? (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))- r/ {3 ?' b6 V" u5 w0 D, z, }: L
return 0;
7 V# I) d" w, `8 w/ e& m //检查历史重复性
Y3 R4 d% i L5 N6 f0 | for(i=0;i<top;i++)" d" ^" w. ^8 w+ M; I5 Y, o
if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)/ ?* U' U' u' s o" @+ C
return 0;0 i# U" g( v9 u/ N
//ok
" c$ v% d! N/ _4 z y, X9 Y return 1;
, W9 _$ l- S1 `, f# x, M1 O}1 k q6 a# U! w6 x
void f1(int top)* t B" x' M% C- { R" l" _
{0 @: L* C0 v: \+ ]. i. g
int m;
$ i% }# g* f2 \9 P if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1
% F& c [% N: \- ]" M { //对每次状态分别试探4中方案
: O8 B; e3 b- C6 H8 G K; d4 I for(m=1;m<5;m++)7 s0 O! i' i2 t0 X( m
{
. M7 M. ]2 B4 r9 \0 B% J8 o //每次方案的实施是在上次结果状态上做的
9 u5 Q$ F3 f/ @ s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
: ~: g4 G* ]* F9 q% \3 Y s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;6 \+ q; S- v P% @' j
//用方案m移动,同时检查结果
6 V7 x) ^/ k1 L% ]0 S* n, _ if(move(top,m)&&check(top))
7 l; h& W: K4 N4 ?( ^+ b9 w. z {
, b4 x. A( E7 k+ }# Y if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ): L' E4 V0 w) o \. i: H# P! t( D, y
{4 I# v0 H. i) }4 e- a ]2 Y
//打印渡河步骤0 S8 M) X" F" @8 k8 C3 o
display(top);
( ~% U4 r8 y5 R5 Q( p7 v+ N2 ^ //统计方案个数
' X( n+ E/ N' ~, `3 d8 l count++; . _( P* h; n5 s/ U! G
fprintf(fp,"count=%d----------------------------\n\n",count);
% L) }, L( {5 @# @" k if(count>1000) exit(1);& ? s. \8 N G: i; M% O
}% M7 N3 W0 O" |. v' a; Q' e+ t
else
2 k; N; ~- C! V9 v5 g f1(top+1);9 t# P4 [- K6 C" Z
}
8 {. ?+ g7 f& q9 O# C }//for9 e+ B" m1 g. H
}//if(top>=0), @2 O9 E, I1 M3 V# l
}//f1
$ x9 C( g% p9 l( k7 c% ~ & `$ M; t" T/ e) R
$ a+ ^$ i! x2 v# t! r/ [
" ~+ S% F2 z! Z7 _$ ?& E
void f2()
4 u) `( r$ J9 A- o, t4 x{
6 s: S* }5 c2 x6 \* c6 u$ C8 _ int top=0,i;
7 J9 L8 ~9 N# S1 v/ x9 ~# W$ G //开始时都在起始岸- G- P2 B6 V: C
s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0; y' d6 |( m5 w* `9 t8 F
//未开始渡河
% W$ I- z2 L* z$ P s[top].m=4;
) }1 ]: }$ ]* ^8 J( { while(top>=0)/ H7 Y1 N! h U6 ~/ @
{( L0 W1 U& U0 `% B
if(check(top))
9 d* y% T: P1 z# P Y {
0 }3 `$ e% ?) u/ ]% J7 p: x' Z if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )9 r7 }5 J8 p* k9 R0 k
{
( N% ^- O& ]2 K+ _ //打印渡河步骤
w9 ^. u& B1 O6 b display(top);
8 ^- m: p% P, C9 v6 _ //统计方案个数
0 o- k1 {& _) w1 K& q% ?) t count++;
: D9 w3 b5 }4 }' R* ~ fprintf(fp,"count=%d----------------------------\n\n",count);
$ _6 ` G8 k7 ^2 @0 |' |1 g7 R if(count>1000) exit(1);: w0 s. w' Z3 o) O* E9 ^: U
//回溯
* }, T) m2 H( [ while(top>=0&&s[top].m>=4) 2 O6 i. u7 F& x* _1 n; a5 u
top--;
5 n! L: _9 i5 q2 J if(top>=0); Q: O4 x+ U7 |; v
{
6 \( G% s- I/ }3 } //在上次状态基础上准备做move
5 w1 \) J9 n+ H( {) M. P s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;) A9 {+ O8 b8 z
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
. r2 i& q4 d/ ^ i=1;4 c% z- p' `3 Y$ Q% y' V( i+ R
while(s[top].m+i<5&&!move(top,s[top].m+i))3 B% ]3 C; v) z$ F1 |0 x0 |
i++;" G' p: @$ s; ^9 G" ?' }
} 6 _7 {% k# a: H3 |3 D. {: d) S5 a
}. J/ m; P: w' T. o7 [0 U7 C
else
& T. B+ q' `& [) d4 d; F {
5 R" ^' M+ F/ K# n+ G$ o6 P4 J: q top++;
! E% s, B) w% C! K/ k3 G- g //在上次状态基础上准备做move
! e8 Z, M9 \+ ?3 ?! i/ B( T. B# x s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;5 F( r& p& O0 A0 ? k+ b5 t* f4 e
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;3 |. G/ M; R7 u$ f2 V+ r
i=1;
, F# x: l( u, c; ]* M' u4 h while(i<5&&!move(top,i))/ @" t. K/ I/ j% l& }
i++;
& B6 J5 k8 u0 w$ f9 h } 9 p& ~; G( U* ]4 S% a
}
. f( F; Q& j9 R" Q else
. `/ R5 ~# A5 L# \0 z {8 P2 B8 u8 v; b f! \9 m
//回溯, w& {( g6 _2 G% j
while(top>=0&&s[top].m>=4) # c- o1 N. H3 R- N% `
top--;# C4 Y9 u' L" E3 J6 O
if(top>=0)! P6 s) o: N7 s. h" o
{
' @: b( g# Y. r$ Y/ b //在上次状态基础上准备做move
7 G: ^, n' L/ {* [( s s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;' V& t+ ?/ ]0 u. ^8 Q2 |5 K8 d
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;: S0 i, u- k, O3 C, l. E1 C
i=1;
/ `5 L. y$ ^! M5 _( v! z0 b while(!move(top,s[top].m+i))/ ~. @% n& }. N
i++;
1 L* R, `5 l7 S) N1 D }* f' r- g9 e& g: d% u: j1 ?
}
; u! ^& M& ?1 |, S* Z0 X }//while/ C( U+ D' p5 `- G( V! B6 z
}//f2
3 X3 o/ [% ]9 A: q//---------------------------------6 v! y- [! H+ P, Y7 I' K# l- c
|