|
渡河问题 ( J. L. L' I# v$ }1 |# T
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?
- j, F7 c/ e$ n 1 ^( \8 E2 M9 m
程序代码:
. u4 J2 y) K( ?+ Z0 Z- \//以下程序在Win98+vc6.0运行通过
! V9 v! h7 F& @' N#include <stdio.h>! _/ l- {" k5 {! |2 N
#include <stdlib.h>
0 f7 c% Y& z2 y( D% c* S9 b3 T#define MAX 50; j* Y3 p* B) q5 [2 h
struct state2 B1 O. H, s' |3 k! Y# e8 q
{ {/ h7 r4 x% ~8 o- V
int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸
5 Z% v" c8 l+ `- y* K int m;//所采取的过河方法,(1--4)9 P e7 w, K5 n
}s[MAX];
0 l" I/ x. |1 H6 [/ Tint count=0;* Q* N( s+ _0 U% Q9 g
FILE *fp=fopen("c:\\2.txt","w+");
# o8 U( V# L1 Y- d" a3 Hvoid main()+ J' X! e' n7 M& ^1 T
{
! U! [6 Q4 @$ \8 q( ] void f1(int ),f2();//f1试探递归- H3 i5 x- U1 S1 l4 P: k
s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0;
3 c' d) W; s' ^, G- X( u: i- p s[0].m=4;
* j# F/ t$ B% D4 u s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;# P/ U4 V! M/ d" j
f1(1);
6 ^" N# b# G9 ^3 B; x% K N4 m8 P //f2();2 V- ~% y; X( n
fclose(fp);+ p' Q( L9 R" W0 [2 G- F6 w
printf("\n");
& b$ M8 x( Y% _ C+ \- r5 s}' b$ q% r7 n7 e) a. B
//用m值决定的方法渡河,成功返回1,否则返回0: g( z1 _( `. u0 I; k
int move(int top,int m)
/ m1 _4 A/ p. n: V+ O( j2 _{
: H8 v8 r& ]) A+ _' s$ @ { switch(m)
6 \2 T) A+ V% e) Q$ ~( J! ]4 k {
% ` S1 B$ i& i; E) B9 a //人带羊过河1 h6 P6 ^* {# ?4 m- E: n2 C& N+ e, ~
case 1: n2 _! ^0 x$ f
//判断人羊是否在同岸
9 M; N% j; n9 X$ p- G% V if(s[top].man!=s[top].sheep) % r9 d$ r( G: X, H" N8 K
return 0;
; L2 ~2 t/ o S% G; I s[top].sheep=s[top].man=(s[top].man==1)?0:1;1 B& l" l- L' k7 z ]
s[top].m=m;//存储过河方法
. X, T; q6 q( X% _: i0 M) \0 i# H break;
% h, o# W7 @* P; W9 E# R* t( A case 2:) f/ Q; E% f# |- [3 {
if(s[top].man!=s[top].wolf); U5 c0 t' e2 B. @' G! f7 W; g, v
return 0;
7 U6 y, ~' U: |0 k4 g3 V s[top].wolf=s[top].man=(s[top].man==1)?0:1;4 u3 T6 H N+ }! N
s[top].m=m;//存储过河方法7 H9 c/ z/ t" X) S8 ~# w0 |
break;
# l3 j+ C7 _2 N) q; ] case 3:
) \% r, I5 ^7 }6 `. e if(s[top].man!=s[top].cabbage)
' L6 m% N% Q9 O) Z( T: h return 0;& Q! r$ Z. {, b; Q+ M# D9 g
s[top].cabbage=s[top].man=(s[top].man==1)?0:1;
9 b7 K0 K) T0 m s[top].m=m;//存储过河方法( I5 U" U2 m! R; F" k3 r4 N
break;5 K( F! \, o% B; x- @/ i
//人单独过河
( o( ~" a6 N% p3 C2 t case 4:, |" ^% n0 ]! k% ` j1 p0 I2 }
s[top].man=(s[top].man==1)?0:1;
9 i$ q8 r2 Z# @1 j s[top].m=m;//存储过河方法
" D7 k* N% c( C1 K. [/ H- y. C% c break;
' A3 P( n; K8 X% N% t' z6 I& C }//switch
2 r9 R" u; \5 t6 n8 J* @9 O return 1;
& C! z) d5 S* A# K5 k4 k, [% K}//move
+ ?6 \0 W) h+ U//打印过河步骤, i$ `' w7 ?4 X2 T8 i% |& v2 g
void display(int top)
- k4 _1 Q8 Y* K5 Y/ h. Q2 b6 z{
3 Z2 U( W! {# u6 N- E int i=0;! A* Y3 f8 V. O; h
fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
* w" d2 V; |& o8 J8 N" z for(i=1;i<=top;i++)9 X. ?' y: M6 |5 k
{
, M5 O# K% M# P/ g' k' y switch(s.m)7 ~4 m7 r5 ~. ^* a
{
- m3 u4 F2 b. m/ G% g2 F+ n4 [( e case 1:
8 A2 p1 Y% p3 H6 g: c1 J0 _! R% l if(s.man==1&&s[i-1].man==0)
: w( T- s& j( b( z; G, b& w) o5 ~# u fprintf(fp,"人带羊从起始岸过河到目的岸\n");7 g: t, ^7 p( T! v# ~9 ]
else
8 l7 x) W% [' j- m- p, B fprintf(fp,"人带羊从目的岸过河到起始岸\n");0 g0 U. G9 |2 R) S* @. D
break;
) k' t- O- H* Z- ?6 M case 2:
* ^. R/ W, G3 B; v8 I% X if(s.man==1&&s[i-1].man==0)
/ J/ Y2 A6 ^, R0 I6 h9 G1 X) }, S' [ fprintf(fp,"人带狼从起始岸过河到目的岸\n");' {! m( O/ u. `; _+ [$ G
else
& h4 q( ]# H- t) ~# J% `, a fprintf(fp,"人带狼从目的岸过河到起始岸\n");6 ^7 C; o/ C/ J
break;! H& s* @( k( T' t ?7 E6 ~
case 3:5 t6 H) v2 G$ v; ?: |3 u) N6 U$ m; b
if(s.man==1&&s[i-1].man==0)7 K% p6 q- S, x! G2 X3 @9 I+ l
fprintf(fp,"人带菜从起始岸过河到目的岸\n");, i2 p/ \6 Z- b( V' O
else
5 f# M$ l" B, G5 t: f) J6 K$ C fprintf(fp,"人带菜从目的岸过河到起始岸\n");7 ^9 I* v( }0 _7 P2 I
break;
1 k1 l* Z" W* \4 | case 4:8 t9 ?) |' U& Z' o, i
if(s.man==1&&s[i-1].man==0)! _" m- p7 e5 Q9 \; I! |
fprintf(fp,"人单独从起始岸过河到目的岸\n");
& x0 [" i2 E& @ else' m: n+ x& n, \: u
fprintf(fp,"人单独从目的岸过河到起始岸\n");
8 i: [3 T# r6 m8 l break;" R2 x1 g! A8 ?6 q5 a
}//switch
3 O4 W9 {7 _/ o2 t. T fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);
. @: T0 ~6 i6 C# n4 Y ! y. b& o; T; y& t5 y
}//for
1 p, D; F& ~7 _/ Y0 }2 Ufprintf(fp,"All ferried successfully!\n");: ^# n( n7 Y5 ?$ n8 G S6 R
}//display
7 V9 n' c/ R% v7 `! `) F, x//检查两岸合法性已经有无状态与历史重复性" ~8 g. i0 O2 |* R
int check(int top)
t0 y- \& i( u, W7 c& Q, [% d2 x{& a& r% V- P4 \7 [; }7 H T" n
int i;
a, X7 s. B# Z1 c//检查两岸合法性, v7 C- Y4 |1 z0 k6 X1 A+ l
if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||2 O- @0 v' q3 W7 g& z1 q4 U7 P
(s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))% O) J3 T/ b3 V& ]* V: V. l. ~9 Z
return 0;- u' ]; D, `9 P
//检查历史重复性' t6 a; Y6 u, `+ b
for(i=0;i<top;i++)
7 l2 s9 H" L6 K7 g; h if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf)
& G5 c" Q1 D3 _/ s3 } return 0;
2 R1 d( z0 M3 K" B1 q, G4 A# ^* m' c& O0 P //ok
& [ t3 w6 v3 w/ F e# n$ |5 U* w return 1;
$ B; j9 F2 m9 {) X/ \}
3 i8 D$ `9 Z3 ?5 mvoid f1(int top)0 y5 ]! Q' P9 k( i
{( ~8 O( |' b# s3 [( Q' j
int m;
0 s& q$ g( K- @( w if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是10 Q- J1 m7 @+ ~7 F+ D# n
{ //对每次状态分别试探4中方案" r* t5 o6 w" B5 Q0 _0 t
for(m=1;m<5;m++)4 @8 w5 I. W% o. O, l* i
{ M/ |. r% q* L* i( M8 i. x
//每次方案的实施是在上次结果状态上做的
+ q& n$ W ?2 X2 S0 K( s' m s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;' D" C+ T) {# J, \" d7 K' m* C
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
- e% w, l, ^1 I+ @& b //用方案m移动,同时检查结果4 d4 ~" p, Z$ @ f- x! s9 |- Y
if(move(top,m)&&check(top))! m" X4 t* b. J: }4 i) U
{+ X# W& b n/ G5 z& l" c( A, G6 M
if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
% @! s0 r' v" u7 {- m {
0 h+ [( E2 x2 |; b4 g' ` //打印渡河步骤
! O* S- C' G Y& E6 q4 A- n display(top);
* p2 r! a9 _( J3 F+ I4 o s //统计方案个数* y7 n/ A9 f9 O4 ~6 T+ S y
count++;
/ Q4 C( Q1 `2 S/ [ fprintf(fp,"count=%d----------------------------\n\n",count);0 s/ |/ O% Z9 r. `3 o" N
if(count>1000) exit(1);
. {( Y( ?1 {% E- m, W& U7 ] }
g- H, \! E; G else& T* Z. T. g8 a0 I
f1(top+1);3 S) A9 _* h W( c
}; ^8 L9 t4 h) q$ c, t" I( G; X/ `
}//for( k! {/ l% G. }: _* @! C
}//if(top>=0)
( P1 S. ]. T( C}//f1
, ]8 t, Q3 J- n / T5 h& z6 S1 V
# H z$ d6 ~8 d3 b& ~3 ^3 @* C! K' o
& n; @2 [6 C$ z2 F* z% Q
void f2()4 j, L6 E! K8 y7 |" h# [- t5 `
{7 J3 O4 j& r2 l) Q* ]
int top=0,i;! S0 x" y+ }' G3 v( L# J. Y
//开始时都在起始岸
# U+ N! l: c2 r0 J s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;
s4 S0 w _* Z. w* X7 |% u% ] //未开始渡河
- _& ~; C' H0 H. e5 e s[top].m=4;% h7 l* R- e! K# ?5 h6 v
while(top>=0) P+ W( K8 |# V5 o
{1 B+ {1 Z# r9 a# K. B
if(check(top))8 k- b* X- ~9 W: G, [5 O/ u
{
- C: |/ ]& ?5 t( {4 X+ D if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )
2 }! Z8 d+ @6 K+ g: e" a {( e1 h4 C+ N! w3 y
//打印渡河步骤) t: X [# T; |
display(top);& z1 N: M; u. F
//统计方案个数
3 O3 w/ V3 |6 K1 |6 y# Y count++;
1 v' O7 ]" U# j4 R; X' t fprintf(fp,"count=%d----------------------------\n\n",count);
" y# S, O9 W k$ Z7 J if(count>1000) exit(1);
& Y- u4 Q* a% d) Q: p1 T //回溯
2 p+ k1 _0 }: B! d" D, t while(top>=0&&s[top].m>=4) ( a( g3 l2 m' _+ c
top--;( Q( p3 f9 f' y; r
if(top>=0)6 F3 {& R5 s5 H5 R
{
7 O/ W. C. \2 y //在上次状态基础上准备做move+ J+ X* ~; Y/ x3 e" F1 N! V: y
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;" g: E1 h! Y& |% f6 b# |* e
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
2 ?/ g, L9 w: @2 d8 L' | i=1;+ [+ U4 ~/ N# x/ L1 ?# D; [
while(s[top].m+i<5&&!move(top,s[top].m+i))- B# w+ `! L4 {6 D3 |
i++;" j3 D/ U0 ^) A2 d/ W m
}
8 z, `5 @# {+ z8 Y. E }4 f1 X+ i3 e5 G. ~ y
else
( ]* a$ }$ A( [* R' O6 Q$ | {
2 `+ j8 S# ^6 \4 Y. _3 \; | top++;& I) \4 O' I6 T2 U- A8 q
//在上次状态基础上准备做move/ N, L5 d) r; t) z5 z( I
s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep; @4 T# I1 O/ E0 S9 x# N. b
s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;' m1 ?- V3 l W% b7 n
i=1;
) ~0 I- |' B. {5 T* x0 ^/ J. G: w while(i<5&&!move(top,i))
c6 `, d5 J- ^, c i++;2 t# I, H& q# U& N
} 7 r5 i a D, L1 j
}6 ?) y& F" O0 _0 U% m: G6 G4 G3 C; ]
else/ K' ~( \5 }5 Y) f" F
{* k$ z5 s S/ _5 ~
//回溯% Z/ k$ m; e4 H# ?
while(top>=0&&s[top].m>=4) 1 H2 h5 [2 ~% v* E* y, u" H
top--;
) y( |& b* V8 h' E. s1 M if(top>=0)' C1 l, _- h6 a
{& c2 @1 ~+ O# Q+ i) K% G( B: I) ~
//在上次状态基础上准备做move
8 O! g1 F6 F( O8 J* | s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;
9 m. Y5 P# d1 U s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;
9 ?6 _" G2 Y7 E. n: g i=1;
5 F6 ]1 M. a R/ n* R while(!move(top,s[top].m+i))
! P- G: f) Y# P5 K4 d i++;0 c- K& ?# d7 z2 V! j+ M
}
" s7 ^; r* }! G: y- S }
6 l' ^6 s4 l# D8 p5 g, i. N }//while1 g% Q. e, |6 M3 b/ z" W/ E
}//f2
/ E/ i3 p* g* W//---------------------------------- ?/ O7 c/ c% p9 E" s
|