QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 7905|回复: 4
打印 上一主题 下一主题

渡河问题

[复制链接]
字体大小: 正常 放大
sally        

10

主题

1

听众

95

积分

升级  94.74%

该用户从未签到

网络挑战赛参赛者

新人进步奖

跳转到指定楼层
1#
发表于 2004-6-5 11:57 |只看该作者 |倒序浏览
|招呼Ta 关注Ta

渡河问题

- z' K0 o, T/ \- b! @+ q

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?

, [' N4 `2 m2 Q

: a0 L2 U/ q2 O

程序代码:

, ]2 `4 M7 o3 m: n) m

//以下程序在Win98+vc6.0运行通过

5 P* x: R) l, }( y9 x

#include <stdio.h> 3 {& R5 w) m' P#include <stdlib.h>7 G2 h }: W2 d' @- o$ @: D0 ^, \ #define MAX 50* G1 Q/ v6 m( X8 L) w struct state9 T; K3 K- S! u! H+ u' K) q {* p2 Q( g4 I7 ? @) s int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸 ! }$ J) g9 v' l7 m s! Y, ? int m;//所采取的过河方法,(1--4)/ D9 d0 A' ?% I+ j/ ` }s[MAX]; " G) W' \' K, ~' m* U# [- ?( oint count=0; * j8 t5 k0 S$ K+ v" |4 i. o: wFILE *fp=fopen("c:\\2.txt","w+");

. n, M* ^1 I. @

void main(); r" }. B! n# x7 n0 [5 v/ i" b { 3 b( B* u W' |2 G* B, {0 D void f1(int ),f2();//f1试探递归* [! M. w2 C1 y: n7 c8 Q s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0; ! B- j# p( G9 e$ \ s[0].m=4;/ r; G" h8 s. Q0 z2 j3 _/ X4 a s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0; * k# Z8 V$ [& l" Q, V z4 T0 Z3 a f1(1); 7 ^2 ^# V C l. F/ O) W1 }6 |8 u //f2();3 o! T9 I* ~# } fclose(fp); 0 z% K' L- B8 Q F2 H$ ` n; j; g% ~% X printf("\n");

+ \5 ]/ ` k0 q) W/ K* x

}# v( I9 Y$ T; C# Y, B //用m值决定的方法渡河,成功返回1,否则返回0 . i* z% H( j& G1 C- Vint move(int top,int m) 6 C @2 V+ D2 W{6 }$ n- g. C" }) E switch(m); l& Q8 A9 t, A" `6 g3 M {' Y, m4 I' J2 z //人带羊过河( G9 [" D c7 a! j case 1: $ P3 ~ C/ C2 U //判断人羊是否在同岸 - u, O1 Q( i1 }+ D- g" n& J if(s[top].man!=s[top].sheep) 2 G( H8 \: o1 S, v! Y% C return 0;9 ^6 U) l& I# |3 B& @ s[top].sheep=s[top].man=(s[top].man==1)?0:1; ' W. N& E7 @3 v6 [9 F* X s[top].m=m;//存储过河方法 3 n7 I! E# e3 i1 n. J break; % T: e& H" r9 z/ w1 C case 2: & J" U! B6 m2 l" M+ Z a if(s[top].man!=s[top].wolf) : r3 _2 U$ P, G5 @ \. H) X1 X: s return 0;5 T k$ h8 a" Z0 U s[top].wolf=s[top].man=(s[top].man==1)?0:1;* v: S- r" I/ S0 r# r' o# r+ {: g s[top].m=m;//存储过河方法 " t( K8 V& ]1 x break;) H' L% O$ P" h) x case 3:/ y0 e [. Q5 \6 |1 i8 f if(s[top].man!=s[top].cabbage)* k8 ^1 O3 \/ e+ I3 k/ r return 0; 3 b1 F% V+ i4 V& S7 q" d4 I' E s[top].cabbage=s[top].man=(s[top].man==1)?0:1;9 h- H% N8 G. T6 B% H; Q! H: _$ f s[top].m=m;//存储过河方法- f0 O& v' L6 A break;0 M) b/ T* y9 H+ Q) g& L //人单独过河3 Q2 e5 Y2 [. E, y case 4:% r5 H# H9 O) Q e s[top].man=(s[top].man==1)?0:1;: z; a" v# M( O4 Q6 ~; N s[top].m=m;//存储过河方法 % {1 @$ D6 U# u, ? break; " i, O3 u5 @5 w* J$ x' f }//switch $ N/ f J6 Q& J; [ }3 s, k( T/ w return 1;7 q, F4 v5 k. K9 g }//move9 B- E) e) g) J/ b3 n! O //打印过河步骤 , k8 J3 r1 [- _( Y4 qvoid display(int top)$ _! }0 y/ }+ F5 U& ^3 x { # z) Y( v* Z* n' X int i=0; 0 @4 q7 M a+ y/ H fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage);# M/ U# M, X/ y8 P/ }( s for(i=1;i<=top;i++)' g% L7 ?; T. m C, U" w2 @4 } {3 A- d; ?! t$ g. | switch(s.m)/ d; v$ c- s: P. f+ \. e {/ ^/ g" W3 d& J) p; z3 w' ~% i case 1:8 D( e, @! o% N1 a9 ~ if(s.man==1&&s[i-1].man==0)" J: _- _9 C6 y fprintf(fp,"人带羊从起始岸过河到目的岸\n");* P" ~5 C0 l, h8 }0 C# k; V; F+ z0 K else 5 i% x; q6 @5 R# i fprintf(fp,"人带羊从目的岸过河到起始岸\n");; m( e7 O" ]6 M; S/ l break; ' E8 c% J- |9 n6 Q+ j2 A7 ^; S case 2:$ _6 J- ~. | C( T4 z' |; a if(s.man==1&&s[i-1].man==0)5 b. {/ Z1 Y! i& i# u fprintf(fp,"人带狼从起始岸过河到目的岸\n"); " Y5 d, g% \" t$ S else2 @, Q9 ]9 x1 ^0 V7 ? fprintf(fp,"人带狼从目的岸过河到起始岸\n"); * ^' |+ B5 |7 E break;$ ?1 R P' I' C$ X case 3:/ o# z, a) C- y if(s.man==1&&s[i-1].man==0) ! [; a- z' k6 i0 H% T fprintf(fp,"人带菜从起始岸过河到目的岸\n");4 U) } Y) _9 n5 o% T1 X else1 s( U/ P; X- k fprintf(fp,"人带菜从目的岸过河到起始岸\n"); / B+ e* _7 y( w$ S M7 Y) t# d break;8 `" s. i' O" B) j! B/ M case 4:$ @0 j+ q' k) M1 j if(s.man==1&&s[i-1].man==0) + L" P& f. Q: f% | fprintf(fp,"人单独从起始岸过河到目的岸\n");- \0 r' r! Q+ C2 ], Q. J- U else ; F, O8 U- a1 X0 N7 K0 w2 ]+ O fprintf(fp,"人单独从目的岸过河到起始岸\n"); / w! e" X& ~6 j0 O! e5 L break; 4 F d' g, @( E, [5 F6 ?6 C }//switch9 R6 _9 H0 W5 t fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage); + O+ _: @% n! t- Q , `+ b( {* c% ^# `) [0 l3 W }//for 1 m( c8 j" X( ]2 @, v# E. kfprintf(fp,"All ferried successfully!\n");' H; Q# a S7 _% f6 x- J }//display

1 d9 J9 j5 S, \$ E0 {. I# n

//检查两岸合法性已经有无状态与历史重复性 : j8 c% o9 I' m7 P) t$ m. e/ Wint check(int top) 8 X' g! o! l& J/ {+ o( H* c{ ' ~7 K3 ~! a2 @# o" a) _4 V int i;' D- \- o- ^/ O //检查两岸合法性 2 o* O; J4 c4 o' t; ?7 Z; { if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)|| ( @% O; ?) _/ r8 l! S (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))' x0 o% V! x" w return 0;+ i. s" \6 j( q, E6 d //检查历史重复性* `' u" C/ m& [* Y. I* U for(i=0;i<top;i++)" \! [. Q4 Y1 L: A if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf) 0 L: o; C9 F" g+ \% k1 B return 0;. w$ q/ N- \# g# D6 S //ok% X$ p6 F0 T( }( T: s3 m return 1;$ M1 Q$ P6 X' p6 n* b }2 \* a# \5 k; O: m void f1(int top); ^& Q( l; W5 D; l" F {: ~- p$ v/ ?" p: \: `( h* s1 n int m; : q( A, G! T9 k/ x$ z! V! Q! u: { if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1+ _: p" X% Y4 `7 E# u# ? O3 p3 T { //对每次状态分别试探4中方案$ h" Z5 C! v1 U1 E0 H$ m8 u/ T for(m=1;m<5;m++) 9 ^7 `% V5 P( w: n9 |8 B( E {% V; q& _# @1 } //每次方案的实施是在上次结果状态上做的 # _# o6 ~ e# l( |" S& J9 m s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;4 X! C- o' B, p, z8 Q/ A% o* W s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf; . C+ l, w. z' R //用方案m移动,同时检查结果 - G* w+ N4 l0 W6 P) r' ? if(move(top,m)&&check(top)) . L }/ |; L2 X, I+ p6 B2 c) p {2 X+ S3 u2 m5 y' ]9 o8 h if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ) ) [9 {- `4 f! A4 V# [8 L {% q- l# a6 C( n" t4 r //打印渡河步骤+ L, x& l' u9 I) b# m( k display(top); $ \. o! j9 ]8 S9 \2 K% o5 s //统计方案个数 . S+ r2 G/ D. K; ~+ i5 P count++; # }) [7 o- v; F# |6 ?; n- j fprintf(fp,"count=%d----------------------------\n\n",count); 3 I* t x6 w: f R if(count>1000) exit(1); / q9 q: n" z1 W! b% R) m }6 S; w& i: T9 f" o" d else $ @- t6 Y6 G5 S9 Q: R0 L" ] f1(top+1); ( t+ w8 a7 h' O+ {: z }" d7 q0 M; c' x* A& |5 I }//for 7 M) Z: W- i5 o* d. k6 |$ V0 c& I }//if(top>=0)" m1 v& f0 l4 C9 T: f/ s }//f1

+ n) N; h7 S9 O7 l3 z# ^9 Z2 ?

/ H" I& a# H1 M2 T9 J

3 D' ^- N. m! G" ~0 S+ P r2 `

: j, c3 a( H# i& ]% ?2 k void f2() ' v$ F2 J8 ~# j/ Z! D/ J{ 2 b* d# E* k* P. ~8 K int top=0,i;% i* I7 ]) A$ Y& j9 c* ]9 \+ i //开始时都在起始岸; `/ G" R; v y8 a: z9 \2 |" B- Z$ ^) N s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;3 k/ d7 i- p7 F; O* W4 r //未开始渡河 * g9 A3 m) R% V6 m6 ~ s[top].m=4; 3 z9 D$ v4 M6 T( E while(top>=0): S# r# S$ Y* X) i. k { 7 a5 r( J) x7 V1 n. w$ B if(check(top))/ L) y. l t5 K8 @- { {' ], B. Y [8 A" p if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )" \0 ?% l) W5 L# H$ W { " h8 l" s9 v$ |: V! h7 r/ w //打印渡河步骤% K) e- n, \3 n) ]0 a' L. ? display(top); % H6 X" j% O6 N9 ]- i. } //统计方案个数 8 V' w( Y [& `/ T* ` count++; ; b8 m% x; K ]% O- d fprintf(fp,"count=%d----------------------------\n\n",count);) _6 U: B) g! r' O if(count>1000) exit(1); 7 w' U% y2 n! ` //回溯* O: p0 C! t9 H8 m+ v, G while(top>=0&&s[top].m>=4) 8 v$ M7 h. l9 y top--; & H$ N! d/ d2 S/ w6 N if(top>=0). P k6 ~+ D: D8 [; J { 8 E) e. H/ o6 w0 }8 c5 y# p" b //在上次状态基础上准备做move. k+ W& p: j7 B) e* V. M* P s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;2 h; n2 S" V1 P: R* J [, E! \! G s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf; : V* v" n+ I, i i=1; : s2 z1 T7 @9 M) U2 T& k0 j while(s[top].m+i<5&&!move(top,s[top].m+i)) y$ k8 F" C+ T) a5 D$ I* P i++; " O! n) _% C8 c8 n0 I# K! i5 b: x }

* P; B7 K5 w* ?3 y: p- v% N, W

}% E% ?+ v8 Y) M h, b1 J& C else# V) N' l* m) r. G { " }1 ~3 ^4 W3 J7 N top++; 9 N; U& Q- y4 F //在上次状态基础上准备做move, ^# S+ x4 K' w1 \# u% b1 e s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;3 ?3 F$ d4 S0 _- Z/ G s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;2 v- @% i3 x2 h0 U2 |3 J/ j i=1;' |2 @4 e" t2 ?7 P _# ^( E while(i<5&&!move(top,i)) / T8 n1 Z5 f* {* M) a, l$ q i++;: N5 V- Q5 [3 K- s- x3 f }

' o* }# `3 S* H0 F" [6 b% r

}# a2 l, _! w3 f: v* o, M else8 s/ @ A" U3 K+ J { 5 G4 R2 ]: e: J& q' J& e0 H //回溯3 c& k, T' f0 c while(top>=0&&s[top].m>=4) ! F" j1 m6 L7 o5 m- Q- U; r2 d top--;% I$ ?1 D( N/ M2 ?+ G if(top>=0); J/ M! ]$ T ]* ~( U r {4 M3 ~+ s* L( ?7 g: O: u2 r! n) H0 [0 p //在上次状态基础上准备做move 7 n3 b0 u. F% n8 X1 i- ] s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep; 3 q8 s8 B* a5 L2 b9 ?9 f8 A s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf;% ^+ {4 i1 Z! @* N i=1; " x/ t6 w* m6 W+ m: E. q while(!move(top,s[top].m+i))0 {0 O+ x+ [, ~) s0 [ i++;' L3 j+ G0 l9 i [, u/ ` }! v. {# b% F' f7 }; `! Q; j4 q }! L! m% }$ X0 s/ |+ I }//while . p; M$ K% ^! l4 h}//f2( D9 M+ `2 Y' P5 |+ D9 z5 f //---------------------------------4 I9 w' B1 K( [" y- U' V3 h

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
阳光总在风雨后
sally        

10

主题

1

听众

95

积分

升级  94.74%

该用户从未签到

网络挑战赛参赛者

新人进步奖

回复

使用道具 举报

1253

主题

443

听众

-516

积分

复兴中华数学头子

  • TA的每日心情
    开心
    2011-9-26 17:31
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    自我介绍
    数学中国网站(www.madio.cn)是目前中国最大的数学建模交流社区

    邮箱绑定达人 优秀斑竹奖 发帖功臣 元老勋章 新人进步奖 原创写作奖 最具活力勋章 风雨历程奖

    群组越狱吧

    群组湖南工业大学数学建模同盟会

    群组四川农业大学数学建模协会

    群组重庆交通大学数学建模协会

    群组中国矿业大学数学建模协会

    回复

    使用道具 举报

    lynn324        

    1

    主题

    2

    听众

    40

    积分

    升级  36.84%

    该用户从未签到

    国际赛参赛者

    新人进步奖

    回复

    使用道具 举报

    mnpfc 实名认证      会长俱乐部认证 

    131

    主题

    38

    听众

    1万

    积分

    升级  0%

  • TA的每日心情
    开心
    2018-12-4 08:49
  • 签到天数: 282 天

    [LV.8]以坛为家I

    邮箱绑定达人 新人进步奖 最具活力勋章 风雨历程奖 元老勋章

    群组2010MCM

    群组数学建模

    群组中国矿业大学数学建模协会

    群组华中师大数模协会

    群组Mathematica研究小组

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-8-3 03:09 , Processed in 0.509145 second(s), 75 queries .

    回顶部