|
渡河问题
4 J- X* D9 r% y/ j* i0 K 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? & U. n" t$ p4 S
3 |5 `$ h* ?$ {* E& L9 |9 a程序代码:
% i5 y6 d2 y5 h" H, |$ T! J" T0 G//以下程序在Win98+vc6.0运行通过
, ?- \" O1 D: B4 O/ Z. Z* f+ I#include <stdio.h>
! F3 k; P/ V, {) E#include <stdlib.h>7 Q. ?3 F4 n3 x- Z. H
#define MAX 504 B' B0 x: {5 Q0 U& g
struct state+ }" W/ |7 m2 z6 u# X: k3 P
{
* M+ I) x* m, p. n" U9 i1 S5 t. P int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸
. t( q0 O' |( t) G& z* { int m;//所采取的过河方法,(1--4)
# b# }( p0 K7 V/ F7 I+ u}s[MAX];# n9 S1 v" x1 N
int count=0; R5 a$ P) ?- ^0 _4 D
FILE *fp=fopen("c:\\2.txt","w+");
+ h" N+ F( K# C0 r6 qvoid main()
S$ n! ^' }+ p: G# u: X1 l! a$ l{5 _/ W1 Z7 `" \+ v
void f1(int ),f2();//f1试探递归
' D5 X1 S- `. m8 a s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
6 R1 q- b+ i5 w, {4 A( O7 P" z r s[0].m=4;
' v* q, g, H5 | a3 _ s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;
) _1 e, U4 W4 f5 ` B f1(1);
6 `/ w) R( d; }; w //f2();4 Z3 b b7 T& n6 M9 n
fclose(fp);
6 R) K- Q: c4 E4 K printf("\n"); 4 y, x: ^+ H4 f. Q
}, R( M5 p+ e" g% c+ ^
//用m值决定的方法渡河,成功返回1,否则返回0& x) R, X/ @+ Z' n
int move(int top,int m)
5 M" G s% s' o( L. N{
- `# j/ L/ K+ O9 \ switch(m)' B: K9 Z2 n6 ?' p
{6 H; g/ }% m. I i" E0 ]
//人带羊过河: l% ?9 V* v& q7 R, A* q1 o1 W5 V/ J
case 1: 5 a" f, B6 a+ u f1 p" n4 }2 S
//判断人羊是否在同岸
) J$ M9 A e/ W if(s[top].man!=s[top].sheep)
! f# Y" F- \9 P return 0;% T' o+ { I! S% }; K1 _% |1 r
s[top].sheep=s[top].man=(s[top].man==1)?0:1;- {; A" q% B z: e
s[top].m=m;//存储过河方法" g) l2 y& E5 R! G- u. }
break;3 J6 v f }3 G' W1 F: u( b+ Q
case 2:/ p9 l3 V' c5 E: _* ]
if(s[top].man!=s[top].wolf)) U- }$ O) g+ v( x/ m7 ^. J9 f
return 0;
8 H& f% C9 X# ^# U/ z3 _& n5 i s[top].wolf=s[top].man=(s[top].man==1)?0:1;" z# }. N6 C% z, d1 y3 o
s[top].m=m;//存储过河方法
" }' @, o& X$ ^% H break;2 K2 d; Y* C4 Z6 r8 K) ^! c% M2 L
case 3:0 K8 B/ s! f" u ^3 j# w
if(s[top].man!=s[top].cabbage)
. g2 e6 X" P% M. k3 D6 k; D/ J return 0;3 q$ P7 N v0 x% I5 u' B
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;& O! M/ s- Z! \6 c) {4 E8 ]
s[top].m=m;//存储过河方法( c9 e1 Z |2 a" L' p) L: Y
break;* K0 ]: \; I) C' m, V
//人单独过河7 t/ }" F3 k4 Y# K' x9 R
case 4:4 b7 c4 M, Q4 s+ u+ g4 p. O
s[top].man=(s[top].man==1)?0:1;
& g; S3 G6 m7 l6 P; W# s s[top].m=m;//存储过河方法
) h# f( F* T& g break;
" O& {, ^2 q/ m) M8 G' w: F% y9 X) i }//switch
+ ^- H0 G7 {) ~7 h# D; o9 C return 1;' q9 r% N+ w8 {& n
}//move
' E3 R7 ^/ I8 L8 P+ ?6 [//打印过河步骤! W9 C! L U5 N6 ^
void display(int top)
. f1 _. ?, g3 {: {4 r r: Q{! {+ J7 M8 S6 Y% s6 c- M0 n' k
int i=0;/ c7 p: m# f& T+ E) g* g. j: p8 t
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);# M6 X6 E0 R8 v% f
for(i=1;i<=top;i++)
+ K7 C2 o* Z3 h) Y8 ~6 A9 c {
( M+ l; [2 s9 q" r' m+ }& O/ m switch(s.m)
/ q6 k/ A& ]" N* e {
) e8 r. }9 u. Y% W+ F case 1:
( ~4 ]2 [4 u, p6 A if(s.man==1&&s[i-1].man==0)$ V8 J4 ^, c# [# g( x9 E% J% v# ?
fprintf(fp,"人带羊从起始岸过河到目的岸\n");
# l. u( o4 ^% K" V' h3 i: p) t else
L; L) S' B+ Y0 u, a9 X fprintf(fp,"人带羊从目的岸过河到起始岸\n");
7 Y# T. S! g3 ^1 _5 P2 {" Q- ~ break;
5 o' x: ^' i, [8 \9 m; e( l2 B1 V0 | case 2:
) ]- |4 e) \$ e3 S$ K if(s.man==1&&s[i-1].man==0). Q* s/ t/ F2 a' T% l
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
$ N6 N( @. f; |& O1 U% \ else
' R5 |& L; _) K2 g' u! h3 m fprintf(fp,"人带狼从目的岸过河到起始岸\n");2 x$ v/ e6 S z! Y' m9 ]
break;
& Z% G: R$ M2 j/ O9 n6 r* g case 3:
! {& q; D4 u. f9 x& H" F4 Y if(s.man==1&&s[i-1].man==0)+ v6 p7 }& b% S/ O. x
fprintf(fp,"人带菜从起始岸过河到目的岸\n");
) ?. Z# X) |( h: d+ e! T) l$ u else
$ O2 D$ x% i) t" Q. v fprintf(fp,"人带菜从目的岸过河到起始岸\n");0 ^; {5 E. B/ z2 G# P. K1 v8 h
break;
$ i; |0 r. M1 _/ u6 n, ^* d9 \2 T case 4:
9 [/ i9 a/ L/ ?; k& E' a if(s.man==1&&s[i-1].man==0)
/ N$ {( g7 g1 R3 t0 ]- x+ v4 x fprintf(fp,"人单独从起始岸过河到目的岸\n");
E: I( [! I1 M, t9 }7 @ else
% O* o, c4 `- P! s1 U( X( H fprintf(fp,"人单独从目的岸过河到起始岸\n");2 Y! A) j7 b, D( b# U
break;
. ?9 N; q4 k$ q4 J) t6 d5 M }//switch
7 J$ m6 a# y2 L- f8 m$ l/ w fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);! Z9 n1 Y0 @* ]( V. Y7 n% U- H
( v' M8 E3 T! _+ w! K) } }//for
2 k9 [6 C: y* Y ^fprintf(fp,"All ferried successfully!\n"); {6 O# L5 w4 h: |1 ?+ W" S
}//display
/ {: z2 p7 X, U//检查两岸合法性已经有无状态与历史重复性+ H k. h% o& r7 Y- O/ A6 L4 C
int check(int top)
! |2 X) g/ t: ^) {) W! L{: l) _# P o8 T/ ~2 E
int i;) l( ? @9 I+ z& ?% W# e
//检查两岸合法性
9 Y: e; q+ G- \6 x( ^ H* c! D if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||& b8 m. g; O3 p7 {3 P# M# I) g
(s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))4 y3 k1 p% P$ c" v I+ a
return 0;
1 H. {2 N" V3 |. K5 n //检查历史重复性4 D- f9 @& m/ ~7 w' ^
for(i=0;i<top;i++)
- ]9 Y3 z# @% Z if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)9 r5 @- |6 S4 [( j, z! R
return 0;6 }- z9 J, L- q; w6 ]0 Z9 Q
//ok# |2 o+ x- e- {6 w3 K
return 1;4 k+ e6 k( _+ o& u9 ^. Z
}+ Y4 N5 n O8 V ]
void f1(int top)
- f5 F8 Y' [2 N; O/ X3 H( @{
% w9 ~* ~- N% ], Y; s8 J int m;( h+ K3 u# w8 R5 _; r
if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是16 J ~8 U/ Q$ c b6 Q4 V
{ //对每次状态分别试探4中方案
4 L0 X$ }- ^# Q/ G6 m for(m=1;m<5;m++)
. o9 a% _# G2 W" X2 o {* l) L* U' y9 O2 y
//每次方案的实施是在上次结果状态上做的9 t# i- s& ~; L% l# @' y& w
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
, @1 z% ]( R j2 B) K s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
" L2 p) q7 d( W0 N7 U //用方案m移动,同时检查结果, `0 F! d m/ j0 v% ?
if(move(top,m)&&check(top))
, v0 ?" ^1 N- j/ J( K! B0 [" T {8 r% K* t+ S$ Q) h. c2 r4 b
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )! L0 q. @7 K r$ f: A
{
7 b! A- Z8 o8 b8 [$ \0 y, R //打印渡河步骤
4 }/ v: q1 u2 I6 ^* X' [ display(top);
1 L5 k& X& p5 u6 Q( } //统计方案个数
/ {- t' V- p6 a( K; A count++;
$ G1 h; X6 w9 @* W4 |6 S Z fprintf(fp,"count=%d----------------------------\n\n",count);; M) A0 F0 U" E
if(count>1000) exit(1);/ w- A9 L: W& u. A: O1 X
}# h9 J* i3 K# v# v: @0 k) t! @' g
else4 G, d! N" I. P/ \
f1(top+1);
' @; ^/ ]- O1 { }& y7 {7 w6 x v+ Z
}//for- |. G( L; D5 K G- h# E
}//if(top>=0)( _+ ~+ ]! A0 c
}//f1
7 a5 | C5 } x% l, j% v7 q D( ?. D8 f. r% k
0 C( b! q& K n* q5 T3 y ' g5 y% c9 T) N& a3 Y1 M; Z! w. Q" x3 D
void f2()
3 r& M/ b$ C4 N$ H5 ?{
2 ~. [9 E7 Z$ w6 {" A6 S1 ~: J) g" A int top=0,i;: b! O3 r, A. w6 B4 Y
//开始时都在起始岸
* `0 e1 U4 |6 q* b s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;
: T k" C) V) H/ a$ S; J# }9 q0 J4 s //未开始渡河
9 F, I& z8 L+ l. |4 [4 z" l) P2 \ y s[top].m=4;
. l- ]. @5 |6 b; u+ V6 [ while(top>=0)- a- X8 A3 |4 X# |; H$ |7 j7 u
{& X; Y1 t: S7 m2 `+ H
if(check(top))/ c! N) ?4 T6 u* E& ~: W: w
{
) a; `7 ]- S& P# G if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ) C/ D, t) Z2 i4 K8 ?* U
{' T; }! h% n1 x; ^
//打印渡河步骤
& p# l$ i* g, }; E( {- h; P% T% q display(top);
9 r. d7 T! Z4 J4 e3 E" Q# ^4 L //统计方案个数
% ?1 G' u6 Y$ q' `1 j count++; 9 L" n9 ~$ {$ H& r+ {. f
fprintf(fp,"count=%d----------------------------\n\n",count);
' ` f6 K$ ~( F1 C5 Z if(count>1000) exit(1);
0 Q% u/ h& v2 ~% n& a( E //回溯; x D2 M6 |9 o5 p) Z7 x( t
while(top>=0&&s[top].m>=4) 7 s: Q" a1 g: T4 l, M% `. z- n$ X
top--;
1 H0 c, H" [( x# v* f0 z if(top>=0): V$ X9 f( }2 t9 _( {
{
' ]7 t; ]1 l2 P+ Z! x" f; { Q //在上次状态基础上准备做move
X) a; `- {1 a7 Q* ^" l }* Q4 i s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
$ N( D6 K' n- ]. P. Z _ s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
; Z7 N; p. b3 F: D i=1; B. W+ j% q k* \) }& w# C
while(s[top].m+i<5&&!move(top,s[top].m+i))
7 Y6 ~9 ]- o6 f8 H+ a, o i++;
# F3 w; T2 @7 X4 x( E }
7 v* S5 Y( U. R3 ^ }
* Q( w" G0 R3 K( y7 {& O0 j/ F else
* \3 e: G9 K2 D& w7 S$ Y {
% f8 d. J9 u9 u' B top++;- L5 X2 @7 f' Z& e
//在上次状态基础上准备做move4 Y5 G$ u' H* v( l; |, v* C f
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
+ o$ u! S# r+ |9 G: H. L. ^ s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
% {" \9 W6 E' `& j. K$ n i=1;
- J8 A, }% [- T; r3 V6 ]2 G: E9 h while(i<5&&!move(top,i)). F. u/ e" K# |& b
i++;
% c6 S* ?$ X( u } ( M. K0 E4 F% N4 t; }0 k+ O
}
" e% F3 c( r2 q1 N/ c, _/ ?1 u else
" ^/ j. N6 m5 M {
* ]7 Z, J8 D! j# R# ~ //回溯
3 a8 Z. g. S% E c1 ?& G0 A6 ? while(top>=0&&s[top].m>=4) & V/ X# k3 W. W6 `) H8 L
top--;
7 p" x8 ]) d, j* H if(top>=0)2 J) a: }$ y/ R! O: ~" a1 C! A/ t
{
) U$ D( Y4 H* Q2 E2 [3 _3 o2 J //在上次状态基础上准备做move4 v8 X, M' O6 t' w
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;- u- y9 z5 ^+ C0 E
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
9 ^& U2 t2 _) Y6 i4 k4 s i=1; . [) o7 e3 Z% k2 C/ @2 j t
while(!move(top,s[top].m+i))$ ]; r* }7 ?/ ]8 u! c1 V
i++;- g/ J3 \) q1 a" P3 K( g7 T( p, U
}
5 u8 R2 {6 O! k2 O }
# `& O T+ T; W4 R ^# G* ? }//while' _$ M7 l5 H+ R2 r r
}//f2' c$ `, d) {% ]1 L% t/ F8 e4 l6 ~3 J
//---------------------------------. M" p. G R; }# i1 I) E
|