|
渡河问题 , D: g* b- `5 {0 G' d- Y: ^
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 e6 N2 G/ E2 B1 H
, n5 w* G# @$ J. X- W
程序代码:
+ h5 G. V: X* c% y# H9 n//以下程序在Win98+vc6.0运行通过
8 f* [! w1 z( q#include <stdio.h>) Y1 _3 c$ A+ c- V! x; W8 ^4 y
#include <stdlib.h>
1 @6 [" V+ @% q# L4 d R7 |#define MAX 50
! o f. G4 V6 B) c* Q" w9 }struct state
/ }4 C4 m; W6 t# u1 d* w' U. N) S{
' p# q* l9 J% S+ I1 o8 j/ l" v int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸) r8 H0 [0 D, e8 I% L
int m;//所采取的过河方法,(1--4)/ b( }( @8 }* s/ [1 _
}s[MAX];# ]' \! V" Y8 V7 J$ M' B/ N
int count=0;0 T8 I4 r# u$ A6 u+ i# \
FILE *fp=fopen("c:\\2.txt","w+");
9 P+ p0 I( p% s' Avoid main()
# h$ R9 J3 p1 v' F1 F{
& e' [" m$ K% V( [, C$ ^ void f1(int ),f2();//f1试探递归
% D. G8 L {6 z! V s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
0 v+ z$ D. L5 y% J" s+ C/ ^' S s[0].m=4;
: P/ t% d- J* w# g1 h s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;3 X3 S! E* c, w# i6 h9 \ L
f1(1);; @0 p( {4 G: F# ^& U. _( p& S
//f2();
4 u; Q% W* {! a* W fclose(fp);
, m# D! X: K- i( q) q/ K" J- R printf("\n");
' h& h" J+ t1 O2 \( Z" V}0 O" Q: w, P' U- w
//用m值决定的方法渡河,成功返回1,否则返回0
* A' \- }1 Z( h0 A2 I) Xint move(int top,int m)0 q0 I, y v2 F/ t
{7 Y" _3 g1 W- u( N; }+ ~7 U8 R1 L
switch(m)/ }' t2 Q; s2 m) G, \
{/ L6 t3 F4 g5 t1 L" i y9 z
//人带羊过河
$ J$ ^" j* A* P# H+ R% H case 1: / J5 Z, N9 c/ A/ U
//判断人羊是否在同岸: X6 L# b( B+ s& J
if(s[top].man!=s[top].sheep) 9 a. C: o- R) K9 t/ u
return 0;
+ m1 D# @3 P( E1 y) F s[top].sheep=s[top].man=(s[top].man==1)?0:1;
2 G/ ?- [8 z9 D4 F( v( M+ U1 W% d s[top].m=m;//存储过河方法8 m' N2 _- S4 d, Y; i: U
break;/ X6 N, ^0 S1 l$ H6 e ]! {
case 2:0 o5 [% e7 K& T3 K
if(s[top].man!=s[top].wolf)
# k* E6 J3 J0 z- t1 @6 B0 _ return 0;4 N( O, M( X0 ~3 i2 @3 E
s[top].wolf=s[top].man=(s[top].man==1)?0:1;
5 p/ \( B1 v9 f( R9 J s[top].m=m;//存储过河方法
! M7 h, }$ e" s break;
( T/ {7 r0 B, b) A; e* K case 3:. j3 y! {. g' K- J: G, ^- j9 o
if(s[top].man!=s[top].cabbage)3 W8 J4 o0 u: J. a+ N( { c+ u
return 0;
- h& k1 v3 u z1 c) V" G s[top].cabbage=s[top].man=(s[top].man==1)?0:1;
N1 z1 Y$ F5 ~& ? s[top].m=m;//存储过河方法
$ k' @2 \* [( r# x break;; a+ Q; b4 H$ {) R
//人单独过河
/ H: N& V/ ~/ R# `) O case 4:) y" Z+ Y7 g9 ]9 q' t# v
s[top].man=(s[top].man==1)?0:1;
0 R9 `; \# j! Q! F) a s[top].m=m;//存储过河方法3 Y# i# U1 E1 m/ J" ]7 H9 [
break;
) v" N) r' Z+ z. Q) z) F }//switch5 T2 ^* w& {! d" O
return 1;4 j6 q7 V& e1 T3 t
}//move
/ k: x3 ]8 M8 o9 N8 u//打印过河步骤
" v) i) {1 P) A P: G) b' Ovoid display(int top)
+ y. u" r# u8 n P{( T; w% L$ J7 n: F
int i=0;
4 [$ X: g. W# g% N fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
2 p% T4 q' Y. b for(i=1;i<=top;i++)$ J" D' \) V( D3 Y' a
{8 I8 ^! |! Q% k6 ?# ?, T
switch(s.m)
X6 a6 \2 i2 ?/ s6 [4 G6 ?; m' c; F {
6 J+ a( p7 {: j- G! o: o case 1:- A0 \, F8 l0 n, G
if(s.man==1&&s[i-1].man==0)% \. l& m9 D$ a7 A8 Y3 k" Z
fprintf(fp,"人带羊从起始岸过河到目的岸\n");
: J. Q% } A8 A3 D, {! G% C else6 s) j" c+ k3 L2 z6 o$ U
fprintf(fp,"人带羊从目的岸过河到起始岸\n");. q1 Y( H: _* @4 J* [) D
break;
" ?: D. ~8 Z6 f2 h. U+ f8 q1 V* y$ _ case 2:
% l2 [9 U. \, p. L7 v if(s.man==1&&s[i-1].man==0); N4 ?0 l- n, M8 |. w' R
fprintf(fp,"人带狼从起始岸过河到目的岸\n");1 }1 k0 a* f' A9 E H+ f
else
/ _7 J5 T: m* c5 o; P) V9 l fprintf(fp,"人带狼从目的岸过河到起始岸\n");9 ^" b {( F8 i3 C+ j# h
break;
; J+ K3 P0 [0 ^3 d& ~! G2 N case 3:
; X! Z1 \' k) v: X d) r( Y- P$ s if(s.man==1&&s[i-1].man==0)
" F& @. L9 X# {$ s fprintf(fp,"人带菜从起始岸过河到目的岸\n");" b1 D+ _. W8 o/ y
else
- A* ~* X3 q+ D fprintf(fp,"人带菜从目的岸过河到起始岸\n");8 L/ |' k6 H1 I7 O& @) G' b
break;" g; b5 Y5 F D1 v! V
case 4:
+ U0 g! u1 B n& X( e if(s.man==1&&s[i-1].man==0)
8 ^- f$ x% I" X9 b# `/ D. ~% [ fprintf(fp,"人单独从起始岸过河到目的岸\n");. E/ k/ Z4 {1 b4 u, Z5 B: m- V
else
9 I* D' ~8 C' F M. H; J; @! u fprintf(fp,"人单独从目的岸过河到起始岸\n");1 x0 U- M0 q4 p! f
break;6 H ]+ z/ x( g0 N7 m5 Y: n8 [
}//switch
+ f# c" L$ k* N% e+ v1 d fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);# p1 f. w) F* S7 N: p# P( H
6 _! @% n4 V2 p+ p' x
}//for2 F8 `3 [/ X5 X5 {, h7 \" ]
fprintf(fp,"All ferried successfully!\n");* B! |* H4 Q( O& t2 x/ H0 g N3 j1 m& E
}//display 8 S: N( e9 |- g) e
//检查两岸合法性已经有无状态与历史重复性
; g+ J7 s! z" a3 k- o! y' v3 S; rint check(int top)9 l$ B& h( r* n0 Q U
{
( B0 r* u( `+ G* T+ I; y* E int i;
+ R+ e4 {1 {5 U; w& P! q* b//检查两岸合法性
0 ]( c+ V1 W7 ]& }3 E0 {$ }! w if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||: D# J) r& I% ]; e1 _
(s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))6 E# d0 K6 L B4 |
return 0;
0 ?; v' j1 d* C' g7 v% Z //检查历史重复性
- I2 ^/ m( j x" s) M5 h7 ` for(i=0;i<top;i++)7 l2 r* J4 Y+ n# P* f1 \
if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)- P+ E; j0 j& v6 ~- |/ M
return 0;
3 J; w3 d( W c q //ok
6 M8 n/ W" z5 v! Q7 H% u return 1;* x$ q5 j" k4 w* [
}8 m4 G1 O8 i- A9 L2 P# F Y$ t/ D1 Z h
void f1(int top) m- n) j# |/ r5 U4 h) q
{
# A- X; I9 k* c# w int m;: l" z; r( D+ O" u# W+ ~
if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1# R9 {; K7 T* b5 R( H \
{ //对每次状态分别试探4中方案
0 u* h1 x9 C* k: f2 P for(m=1;m<5;m++)2 k; _% J( N1 M' S7 z9 r/ P
{- Y0 j) Q j2 {7 M4 I
//每次方案的实施是在上次结果状态上做的+ `" w# I4 T: M
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;7 Q3 e4 o- a' P" }- d/ u
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;0 _& s3 S( X3 F8 m8 i
//用方案m移动,同时检查结果
2 {9 [ W; ]0 l4 E3 X$ J if(move(top,m)&&check(top)): x- Z: J0 E4 u! p& Y% I
{
* x& \+ S, x1 x. w7 k if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
- p& ^/ R# _1 s* V+ ^7 h {
9 v! k* I* N4 V+ G //打印渡河步骤
' X3 J) k l9 |/ r6 W+ p5 M% `3 O5 q' ~" W display(top);5 P& t* e ^& E5 y8 v
//统计方案个数: m( Q* W: B; @0 a
count++;
5 O/ U$ z* B' B6 u4 } fprintf(fp,"count=%d----------------------------\n\n",count);
n; Z( }- N9 j1 I5 J, L if(count>1000) exit(1);
4 y6 |; u: t* L4 u# q% k: g; c }5 Y- P p: E7 }/ G
else
( H3 F/ [# a" f9 p f1(top+1);
5 i& P4 q- i. z+ P, R }, ~ @$ }# g, R6 Z7 N. n
}//for% F# ?7 N0 N! j6 _. A g$ T
}//if(top>=0) K8 j7 B& b* h8 U
}//f1
5 J \' p l7 ~8 j* p3 f
6 y6 {6 {6 s/ H' v+ O/ F k. Y+ V( @1 O
! x6 c9 x! H* i9 G+ ]9 J
void f2()
6 I. y |# O* d% s# I6 O/ P{
0 A. M5 U @' u int top=0,i;
) G( z% V/ i J( M. X //开始时都在起始岸
5 h. N. l# y* m7 U7 {0 T s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;
6 S2 T6 D8 j r0 t% u //未开始渡河6 \* [5 B) A: v
s[top].m=4;
9 c7 ?1 M% R7 g) _ while(top>=0)$ ? l1 r, L9 D; l2 I
{6 h: G+ e; o+ B7 A
if(check(top))
" \6 S2 B) G6 @; X& S+ d8 @) B) M- A {' @& r9 x, Z8 A, q/ S$ ]2 u
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
* C- P W( L& ?0 Z, ~" j {: I' c7 E) ?% Z) M- ]1 V4 u
//打印渡河步骤( ?) s+ v, v/ K4 L. ^3 y8 G7 f
display(top);
: p. c$ A& L$ [( }1 P7 ^ //统计方案个数
1 K4 N6 k" L' C( ~* b; ~; I, n4 ? count++;
: `2 H& x5 X; }. E: t fprintf(fp,"count=%d----------------------------\n\n",count);/ d5 U4 M2 i- k/ G
if(count>1000) exit(1);5 z) \7 c( E: D8 _. Q
//回溯/ ^! Z+ P$ K& e- l. d' v
while(top>=0&&s[top].m>=4) : ?5 n& }. V/ S) `
top--;2 `) ~4 a: D9 E! j4 @4 V: \4 h, v5 m
if(top>=0)
: H' y! d6 ~$ f# M {, d0 l3 I1 L8 J& V1 ?
//在上次状态基础上准备做move
6 s1 y; l( g) D2 X* G+ r! F6 K s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;7 z, A. }5 N* m( [$ {
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
0 F* f8 ?& ~: Q+ ?7 f0 A$ m* l i=1;
: c% k9 O6 s* q1 {/ k while(s[top].m+i<5&&!move(top,s[top].m+i))
. a3 ~' w- }* n5 w6 v: W7 E i++;7 E8 o6 N* M3 ~1 k$ d& k
} , e) }' `0 n, }4 x( {( H; f4 r& j
}) H6 k! E. C9 c0 X M3 s% G# g7 P7 z$ D
else
7 k! p: F) S$ l5 G {* ]( X8 f% Q# x
top++;- t# I) S2 s; O, u
//在上次状态基础上准备做move
7 p* U$ N* R/ [5 z s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
7 p5 Q( c9 k( h: O* I) @ I! i s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
+ T+ F- R8 R* s0 d$ a; u i=1;! O+ |- m; a5 n% _, V* i
while(i<5&&!move(top,i))& R; s$ e& |- \& [
i++;/ w' N- ^" z/ |% Y7 v, u
} % \* T- o2 L. {
}
. d" s4 A( ?4 p/ h else4 ?6 l* u* H/ y7 @: _# W
{3 T$ Z5 e' ?! K1 ~. z# U" X* k- ~
//回溯
7 ]2 i0 g A0 f4 d while(top>=0&&s[top].m>=4) , T0 P, p. C8 R9 R
top--;
7 _2 I- q7 _+ ^. u1 Z if(top>=0)- o7 e1 N$ h, |% R K- s+ l
{3 I" \7 I) o- A9 Z8 A& m2 A
//在上次状态基础上准备做move
) B2 }% N5 Q m s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
# x9 g5 v3 U& d# L3 s s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;, t% Q$ j& y7 A6 |: u5 H
i=1; ; y0 C& `, d, Q# }/ E a( x
while(!move(top,s[top].m+i))
: D9 t! J. y$ T8 R i++;9 z& L1 `6 P: [& z6 w6 i
}5 _* [* I! I" O& W9 u
}
: z; ?; p- w t% Y# c }//while
' {+ c$ l# w3 y- ~" e1 N- j q}//f2
3 |+ Z/ n- H6 }8 k//---------------------------------6 h: G3 }4 j9 ], s
|