Romi-知行合一

轻轻的风轻轻的梦,轻轻的晨晨昏昏, 淡淡的云淡淡的泪,淡淡的年年岁岁。
  博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

手机游戏——蜘蛛找出口

Posted on 2012-06-02 14:34  romi  阅读(1016)  评论(0编辑  收藏  举报

以前用诺基亚时,手机内自带有“智力王”这个游戏,其中有个小智力项目考察的是蜘蛛在诸多蜘蛛网按一定规则爬行,然后判断蜘蛛最后会从哪个序号的线中爬出来。本文中使用C语言实现该模型。

如下图所示(最左端数字代表横线的高度):

游戏规则

蜘蛛从上边任何一个编号处的线开始向下爬行,一遇到横线就转弯沿着横线爬,爬到另一条竖线就沿着该竖线向下爬,遇到横线再转弯。。。以此爬下去,知道爬出蜘蛛网,然后判断蜘蛛的爬出蜘蛛网的出口是编号为多少的线。

就按照上图所示,假设蜘蛛从1开始爬,则会依次经过1-2-3-4-3-2,最后出口为2。

使用程序语言实现该功能。

输入:1.蜘蛛网竖线的条数;

        2.蜘蛛网横线的数量;

        3.蜘蛛开始爬行时的竖线编号。

        4.各横线的起始点和终止点所在竖线编号以及横线所在位置。

输出:蜘蛛最后爬出时的竖线编号。

为了简化模型,假设输入为三个数N、M、K,分别表示蜘蛛网竖线的条数,横线的数量,开始爬行时的竖线编号。竖线从左到右编号依次为1,2,3,4....。每条横线由三个参数决定:起始的值xl(表示与横线左端相连的竖线的编号)、终止值xr(表示与横线右端相连的竖线的编号)、高度y(表示从最下端0开始的高度,正整数)。

比如,对应上面的图,蜘蛛从1开始爬,对应的输入输出格式就应该如下:

输入:

5  9  1

1  2  8

1  2  5

1  2  3

2  3  7

2  3  2

3  4  5

3  4  3

4  5  7

4  5  1

输出:2

编程实现

这里最关键的是根据上面的规律通过数学化的语言方式将模型表示出来。

这里用M长度的数组xl[]、xr[]、y[]存储每条横线的参数信息。

假设最开始蜘蛛在编号为k的竖线上,向下爬,如果该条竖线上有横线,则xl或xr数组中存在元素的值为k,然后找出离蜘蛛最近的那条横线,找到后,如果是xl的元素,则蜘蛛到了k+1的竖线上,如果是xr的元素,则蜘蛛到了k-1的竖线上,然后依次类推,循环查找,每次都是找出比当前蜘蛛所在高度小的最高的那条横线,如果不存在相应的横线,则那条竖线就是蜘蛛的出口

根据上面的描述,可以使用一个死循环来判断蜘蛛的爬行路径,找到出口后退出循环。

代码如下:

 1 #include <stdio.h>
 2 
 3 int groupNum;//测试数据组数
 4 
 5 //判断蜘蛛最后的出口
 6 void check(int n,int m,int k,int xl[],int xr[],int y[],int* value);
 7 
 8 void check(int n,int m,int k,int xl[],int xr[],int y[],int* value)
 9 {
10     int tempy=1000001;
11     int temp_prey=1000001;//记录本次爬之前高度
12     while(1)
13     {
14         int step=0;
15         temp_prey=tempy;
16         for(int i=0;i<m;i++)
17         {
18             if((xl[i]==k)&&(y[i]<temp_prey))
19             {
20                 if(temp_prey==tempy)//第一次碰到横线
21                 {
22                     tempy=y[i];
23                     step=1;
24                 }
25                 else if(y[i]>tempy)
26                 {
27                     tempy=y[i];
28                     step=1;
29                 }
30             }
31             if((xr[i]==k)&&(y[i]<temp_prey))
32             {
33                 if(temp_prey==tempy)//第一次碰到横线
34                 {
35                     tempy=y[i];
36                     step=-1;
37                 }
38                 else if(y[i]>tempy)
39                 {
40                     tempy=y[i];
41                     step=-1;
42                 }
43             }
44         }
45         if(tempy==temp_prey)
46         {
47             *value=k;
48             break;
49         }
50         k=k+step;
51     }
52 }
53 
54 int main()
55 {
56     int N;//蜘蛛网竖线数量
57     int M;//蜘蛛网横线数量
58     int K;//蜘蛛开始爬行的竖线编号
59     int result;//记录结果,蜘蛛最后的出口
60     scanf("%d%d%d",&N,&M,&K);
61     int xl[M];//记录每条线的起始x轴
62     int xr[M];//记录每条线的终止x轴
63     int y[M];//记录每条线的高度
64     for(int i=0;i<M;i++)
65     {
66         scanf("%d%d%d",&xl[i],&xr[i],&y[i]);
67     }
68 
69     //切记:最后一个参数不能传值,必须传地址,这样改变的值才能得到
70     check(N,M,K,xl,xr,y,&result);
71 
72     //打印结果
73     printf("%d",result);
74 
75     return 0;
76 }

核心就在check函数内,判断蜘蛛最后的出口,其实并不难,就是蜘蛛不停的的爬,按照既定规则爬,直到蜘蛛再也找不到转弯的横线时就算找到出口了。

测试结果

经过测试与实际验证结果是相同的。当然也可以设计更复杂的蜘蛛网进行验证。

对于前面给出的图中的验证示例如下: