|
渡河问题 $ j3 X, s* G- T, ~* i0 u! }
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? 2 C N( z2 E: I5 }" P7 }
$ G8 s% z& _9 Y u1 \. K程序代码: % |0 G* ?6 m3 e# _ A
//以下程序在Win98+vc6.0运行通过 / D! T/ C! v: ]) d" B! B
#include <stdio.h>
5 `5 a5 x7 R$ ~ y& K& p2 f#include <stdlib.h>9 {& k P6 L3 j; Q' l- a
#define MAX 50
5 [( R+ b9 ~- w, S! T* o' H% Kstruct state
/ m: ~7 X4 p$ C! t7 A2 s9 u{9 S3 |" k% [* g' N- _4 Q' }( v6 I
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸5 y% C- \4 i/ P' c
int m;//所采取的过河方法,(1--4)
6 \0 \0 u( k6 n# A& ~}s[MAX];
& G! v1 j: W, @8 O6 xint count=0;8 s+ k( a) l4 B+ }3 m5 }' p
FILE *fp=fopen("c:\\2.txt","w+"); ' ~. r: i' ]+ J9 O7 p
void main()* b1 o, @0 h, J
{* x# B% P# s" f3 F% M6 C
void f1(int ),f2();//f1试探递归) U' G3 q: q6 r! S
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;" t1 r R W! Q) O
s[0].m=4;
3 v# r" h0 K0 \1 F s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;/ f% l% }# r. n6 ]- _4 f/ Z5 n( U
f1(1);; j, O0 F- C4 t0 {+ S6 d4 S
//f2();2 s% v& \( v) t; F6 \* c* ^& u1 G
fclose(fp);
; T' h( p$ C& v8 O$ B7 F printf("\n");
' @" W. _" M3 F- L- i4 N0 [}6 W) Q$ y( o1 I- E5 G! u
//用m值决定的方法渡河,成功返回1,否则返回07 R. G# V6 o7 @. {5 N/ a- ?
int move(int top,int m)0 S# b7 n" S c( U: Q' v
{
0 m) U, u+ I8 i switch(m)
6 R j; d, ]- m" o# w; r5 a# _7 K3 \ {
5 T. a* O! w6 } }/ v3 w //人带羊过河3 {8 o! O8 M- n; N$ q8 g8 X4 V
case 1:
% y$ x9 y% [6 Q //判断人羊是否在同岸
3 W4 a0 _: m y: M0 f! ` if(s[top].man!=s[top].sheep) . p3 |5 k' P6 b/ I' n/ G9 [
return 0;
3 n+ L; H. Y0 z s[top].sheep=s[top].man=(s[top].man==1)?0:1;6 y4 Y7 [' y2 Y
s[top].m=m;//存储过河方法
8 E. q# r8 B# o1 T: z break;
+ B: u) {" u+ n- Q' o$ n. s, I case 2:
; @ G- O; b+ c; C' N/ ] if(s[top].man!=s[top].wolf)
' F# C: ~; D5 D4 o9 [4 A+ T6 y) i return 0;9 \& M; I$ q5 G' y0 M' P
s[top].wolf=s[top].man=(s[top].man==1)?0:1;
A" F; M6 ?- I, i |' f2 c s[top].m=m;//存储过河方法& l( M4 g0 r& K* e. m" f
break;2 }8 R; K% ?" E7 M3 K2 p
case 3:
1 s `. u( i; l4 a+ L1 C: z if(s[top].man!=s[top].cabbage)% _$ o5 c# o- J2 g/ S r
return 0;
0 O O! ?) d% `, `6 I% e1 o+ \7 | s[top].cabbage=s[top].man=(s[top].man==1)?0:1;
6 r, Z' ?% S! @) K1 i% N s[top].m=m;//存储过河方法; X* j( P# t3 a
break;
" d* _: o( K8 o) | //人单独过河
6 u; I/ A, E& n! G, i$ e9 B case 4:
: h* r* Z- Z2 Y( m s[top].man=(s[top].man==1)?0:1;
& ]) r! Y% H. F4 J s[top].m=m;//存储过河方法1 b9 O& X- \6 {; x1 B
break;/ ?" U5 V& [$ |5 f7 N# Z
}//switch
/ J, Y7 ~& U s% L, v0 G return 1;+ g" D9 h( E, a( l) F1 D
}//move8 h6 O, {* z/ s# R/ r
//打印过河步骤7 r, c" X N) I. `$ w# p: W' A
void display(int top)
& M. l* o9 A7 J- T{5 Y/ Z5 U6 m5 X& j
int i=0;
2 D6 J8 c& u9 x7 T fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
+ o7 |. ?& k6 ]& Q8 ~ |8 ] for(i=1;i<=top;i++)
+ \- Y: v W& }5 c! l( L- I {4 p1 w( N8 Q' [- b* \4 R
switch(s.m)
$ M/ V& a& n7 I' c3 } {
: e: T8 N0 U% A4 g' G& r; g case 1:: _9 I- Q% T' G1 y% u+ [4 A
if(s.man==1&&s[i-1].man==0)
: p+ d, E/ R3 K1 C6 W" I4 q fprintf(fp,"人带羊从起始岸过河到目的岸\n");" E: c' u' h2 B5 [+ [
else; @8 \4 Q4 @5 c F
fprintf(fp,"人带羊从目的岸过河到起始岸\n");; a, b1 B* h! c; }3 o+ a
break;) M" H- ^6 r4 q) j$ Q& D' Q
case 2:2 B( g; [% w1 s% v$ i0 i
if(s.man==1&&s[i-1].man==0). Y! v2 n, L0 i, b
fprintf(fp,"人带狼从起始岸过河到目的岸\n");
5 h6 S5 ^% y- O# O- T2 Q else7 ~6 f# O; t k" ]2 T9 D; i, X
fprintf(fp,"人带狼从目的岸过河到起始岸\n");) l2 N* h7 L$ Q, Q
break;- T: G/ M2 s1 y, A
case 3:) b! x% f+ D- y" o T5 H
if(s.man==1&&s[i-1].man==0)
: |' ?1 s( q: H2 X! } fprintf(fp,"人带菜从起始岸过河到目的岸\n");5 N' K3 h! v7 R/ f# \
else
+ n W$ i: Y! J- A( |5 s fprintf(fp,"人带菜从目的岸过河到起始岸\n");
- }. |1 T5 I1 n% N& g3 h break;( q3 z h* ?" b/ X4 _5 M5 x( U
case 4:* O. E; L1 B8 n5 M5 B
if(s.man==1&&s[i-1].man==0)
# K6 B( _ E) `, Z! a fprintf(fp,"人单独从起始岸过河到目的岸\n");
! @* C# @. Z# b7 c& g- u0 G# S else6 W6 K" a0 E/ G' x( |
fprintf(fp,"人单独从目的岸过河到起始岸\n");( v) D2 s, m4 l$ I
break;" s" y* z- f! ~
}//switch) O# N/ r" a, o s1 A
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
( ^. D: t( h4 ]7 T* V4 Y" q
9 E4 [& h) M7 w" ? }//for! `9 {( E' }( [" m$ ?6 n q
fprintf(fp,"All ferried successfully!\n");
- ?# \! x; w. m" w/ g6 w7 v}//display $ r5 J1 P! q6 f6 [* P9 f& c
//检查两岸合法性已经有无状态与历史重复性% k/ S" q. B: c: C. m- C
int check(int top)3 L6 Z x, }9 O2 ?; H
{
: f5 r U/ t }! m+ z: C$ S int i;4 D& V. I6 e' a
//检查两岸合法性
& b l+ w4 g: M7 G2 y* b if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||
7 A7 \/ n* j: C+ `& }* `" W6 I (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))! J, c. u; b- l4 n5 c) x: j# \
return 0;
+ T0 G$ |/ S' `0 u4 B //检查历史重复性6 x/ _' d4 }+ Q5 b" V
for(i=0;i<top;i++)
$ t7 A; z5 J' O E( p, u1 s$ \ if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)
: t4 q5 K: U" s6 }# N0 t: m/ @ return 0;9 x' d- Q2 q. C3 \2 {9 L
//ok
3 X) ~- Q9 i" E5 Z! k: }$ G return 1;
- J' `$ Q1 I' {# x* s}9 i& b |7 D& s' F [8 _# v0 q( `
void f1(int top)( z8 d8 I( q$ ~8 U( V4 N+ M
{1 s% P% Y5 s2 K( f
int m;
! q1 K/ ]& Q( V# f2 z$ H if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是17 D# S$ w5 [4 b4 T
{ //对每次状态分别试探4中方案
( V" [, W3 o! k1 q# N5 d for(m=1;m<5;m++)- P* ^$ U' v8 g0 T5 S+ |" I" O
{
* a8 a' G& ~0 |; r A) ` //每次方案的实施是在上次结果状态上做的
3 g+ d/ I0 K _* H k s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
6 g. e; W9 Q' O s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
% u' E4 t) b) C //用方案m移动,同时检查结果% O: _( W$ ~6 J: I7 u
if(move(top,m)&&check(top)), Y! u( Y9 F6 i# s- Q
{$ x+ _( K. {8 J. c
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
6 P9 w" f% f5 V' b$ ~9 B {2 B' `2 C- C) h9 y
//打印渡河步骤$ x( n& h3 B. H1 q9 f
display(top);# S3 D7 p; ^7 |
//统计方案个数* J! u( \+ V' d) k7 _' P
count++; $ e! c9 `- P& b" f
fprintf(fp,"count=%d----------------------------\n\n",count);" v# t. s& G7 I% Z# j
if(count>1000) exit(1);+ b7 u! G: w8 `( }7 Q3 U
}. q7 f# M8 P% J
else! z2 ?* [0 K- S/ K! |
f1(top+1);
' h/ E% e7 A" u1 ^ }- L8 f' X. e/ w; n
}//for
) h; h) D3 x1 R2 w }//if(top>=0)
$ Z# c- d8 c( @0 \}//f1
. W# n. K4 V: @+ t x) a; r2 v A& P! a/ W. V! f' V
' H8 A+ L, G3 N6 m, C$ B3 t+ U5 t
# s' ]9 @0 O s: Nvoid f2()0 U0 D& [% H# ~5 z
{2 O8 Q9 _ X8 H1 q& \
int top=0,i;5 W( k' e5 X' I" `( \. |& v
//开始时都在起始岸
# W4 Z$ e; a; P; i3 z s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;( n0 m' G) ]# q+ G
//未开始渡河
, I6 s% W; h b* k) s5 \ s[top].m=4;
; ]8 I) C7 w, t0 v, Q, o while(top>=0)8 f, t9 q1 M) ~6 ~. V1 t
{# P7 \; z1 q( r# _3 l+ R1 R. ?# L
if(check(top))" ~3 ~* g! J' C9 ^7 v$ w
{
( @9 A9 `2 U- G* M. w2 W if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
1 \8 c" G( E( h( T( k) p5 |: v {2 i! f8 @% q3 ?5 Z
//打印渡河步骤
1 R" \% m, U0 t4 G9 e* F# r' T display(top);
$ x# O# }/ J, _) n/ N8 y3 P, z# p //统计方案个数
* Y( `, N# W& H count++;
1 [! V0 S1 m; A6 Y fprintf(fp,"count=%d----------------------------\n\n",count);: Q& A4 r* q' Q. n+ J* ~# i5 u
if(count>1000) exit(1);
( _9 R m& X4 |8 k6 F2 e8 @ //回溯2 ?! ?( R8 I; a G; o1 X" b
while(top>=0&&s[top].m>=4) . _: ^+ @6 o! B5 p+ u: Z, G
top--;3 v L# b: ^4 b3 G
if(top>=0)$ t! }6 u) P0 u
{1 s4 F, s d* [8 e
//在上次状态基础上准备做move
. F$ `, N- R6 u9 q, B s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
# b- [! n: i: l5 o2 @ s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;4 f# H% }# a& n& Y3 f4 D
i=1;
* n1 q/ g& q% l# F while(s[top].m+i<5&&!move(top,s[top].m+i))9 s4 {4 U7 R& F
i++;
0 M3 t! k" V; O' b7 H- | } $ U& O# o( `, W& ^% D) h. g
}
8 T; t* z: j) s) I' A else
& v7 {3 G" M3 q" {, W { L3 V$ T" k6 q& I$ ]1 q8 _
top++;
1 m) x' b8 P# a //在上次状态基础上准备做move
) G+ u2 P0 ~, d$ r s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;2 E. ? O$ n0 ^4 E5 r
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
: D; w$ }4 Y1 O% y i=1;
9 ~ B. d! f& A. m% T while(i<5&&!move(top,i))8 `1 @' D7 _# D. O: |2 o" S
i++;+ D8 |: |+ j: v7 U
}
R. s8 ^$ F- O, `0 Z, i& s1 z5 s }
1 Q! S- n; @( K5 [6 Z1 U else6 D4 |) `" L! I7 I
{' q" l d$ |7 M! \5 c: h1 U
//回溯
9 N8 J* A: l/ T$ ` G) m7 x while(top>=0&&s[top].m>=4)
1 c8 [3 q7 u* N top--;, [% k2 m$ q+ b8 L* C$ I& p
if(top>=0)$ ^; p! y' K# x {
{
u1 l1 v2 W/ ] //在上次状态基础上准备做move
- _! H0 P1 a0 S s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
4 h- @# Y3 ]% p s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;9 T/ C& r: W# u6 V" r$ R n
i=1; ' r) S. D/ D2 Y) Q
while(!move(top,s[top].m+i))1 M+ f9 ?, D, X3 U: h8 T
i++;4 L5 {+ J5 P9 g! \6 @* _* ^% M9 p
}1 V0 A" y6 i4 p4 b3 \) ^6 t
}
% n0 o$ E# F2 K& a3 X3 i$ V( F }//while$ a! j! G. ]7 T- I- ^% E2 t2 h
}//f2# H( ~2 g! V' W7 O( ~( N
//---------------------------------
! _6 E* O; v- M- `- ~ |