- 注册时间
- 2007-12-27
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 40149
- 在线时间
- 小时
|
楼主 |
发表于 2008-6-6 15:16:17
|
显示全部楼层
现在介绍一下我的思路以及整个计算过程.
第一个版本是非常简单的穷举代码,这个版本只能计算n=4的情况.
我们假设所有数据按增序排列,由于第一个数据只能是0,所以我们可以枚举后面三个数都在某个范围内的.
为此我们可以定义一个三位数组-
- #define LIM 100
- #define N 4
- int rch[LIM][LIM][LIM];
-
- #define SET(x,y,z,v) rch[x][y][z]=rch[x][z][y]=rch[y][x][z]=\
- rch[y][z][x]=rch[z][x][y]=\
- rch[z][y][x]=(v)
-
- #define TARGET(x,y,z) (((x)<<16)|((y)<<8)|(z))
- void init()
- {
- memset(rch,-1,sizeof(rch));
- rch[0][0][0]=TARGET(0,0,0);
- }
复制代码 其中数组rch[x][y][z]被初始化为-1,
然后如果序列0 x y z最后能够成功到达0 0 0 0,我们将rch[x][y][z]设置为TARGET(x1,y1,z1)
其中0 x y z可以直接到达0 x1 y1 z1而且0 x1 y1 z1也可以到达0 0 0 0
然后我们只需要从小的序列开始计算到大的序列就可以了.
其中最麻烦的就是我们需要计算对于某个序列0 x y z,它可以直接到达的序列有那些
下面的函数int pass(x,y,z)实现了这样的功能,对于给定序列0 x y z,它返回TARGET(x1,y1,z1)或-1(如果无法成功)-
- int set_reach(int x, int y, int z, int t)
- {
- if(x>t||y>t||z>t)return -1;
- if(x<t&&y<t&&z<t)return -1;
- if(rch[x][y][z]>=0){
- return TARGET(x,y,z);
- }else
- return -1;
- }
-
- #define set_reach_0(a,b,c,d) set_reach(a,b,c,d)
- int set_reach_1(int x, int y, int z, int t)
- {
- int r;
- if(set_reach(x,y,z,t)>=0)
- return TARGET(x,y,z);
- if((r=set_reach_0(x+1,y,z,t))>=0)
- return r;
- if((r=set_reach_0(x,y+1,z,t))>=0)
- return r;
- if((r=set_reach_0(x,y,z+1,t))>=0)
- return r;
- if((r=set_reach_0(x,x+1,z,t))>=0)
- return r;
- if((r=set_reach_0(x,y,x+1,t))>=0)
- return r;
- if((r=set_reach_0(x,y,y+1,t))>=0)
- return r;
- if((r=set_reach_0(y+1,y,z,t))>=0)
- return r;
- if((r=set_reach_0(z+1,y,z,t))>=0)
- return r;
- if((r=set_reach_0(x,z+1,z,t))>=0)
- return r;
- return -1;
- }
-
- int set_reach_2(int x, int y, int z, int t)
- {
- int r;
- if(set_reach(x,y,z,t)>=0)
- return TARGET(x,y,z);
- if((r=set_reach_1(x+1,y,z,t))>=0)
- return r;
- if((r=set_reach_1(x,y+1,z,t))>=0)
- return r;
- if((r=set_reach_1(x,y,z+1,t))>=0)
- return r;
- if((r=set_reach_1(x,x+1,z,t))>=0)
- return r;
- if((r=set_reach_1(x,y,x+1,t))>=0)
- return r;
- if((r=set_reach_1(x,y,y+1,t))>=0)
- return r;
- if((r=set_reach_1(y+1,y,z,t))>=0)
- return r;
- if((r=set_reach_1(z+1,y,z,t))>=0)
- return r;
- if((r=set_reach_1(x,z+1,z,t))>=0)
- return r;
- return -1;
- }
-
- int set_reach_3(int x, int y, int z, int t)
- {
- int r;
- if(set_reach(x,y,z,t)>=0)
- return TARGET(x,y,z);
- if((r=set_reach_2(x+1,y,z,t))>=0)
- return r;
- if((r=set_reach_2(x,y+1,z,t))>=0)
- return r;
- if((r=set_reach_2(x,y,z+1,t))>=0)
- return r;
- if((r=set_reach_2(x,x+1,z,t))>=0)
- return r;
- if((r=set_reach_2(x,y,x+1,t))>=0)
- return r;
- if((r=set_reach_2(x,y,y+1,t))>=0)
- return r;
- if((r=set_reach_2(y+1,y,z,t))>=0)
- return r;
- if((r=set_reach_2(z+1,y,z,t))>=0)
- return r;
- if((r=set_reach_2(x,z+1,z,t))>=0)
- return r;
- return -1;
- }
-
- int pass(int x, int y, int z)
- {
- return set_reach_3(x,y,0,z-1);
- }
复制代码 |
|