ACM-奇怪的电梯(广度优先搜索、AC)
2012-04-27 01:01
197 查看
奇怪的电梯
Time Limit:1000MS Memory Limit:65536K
Total Submit:19 Accepted:6
Description
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有2个按钮:上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?
Input
有多组测试数据!对于每组测试数据第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。
Output
对于每组测试数据请输出一行,即最少按键次数,若无法到达,则输出-1。
Sample Input
Sample Output
Hint
多组数据输入方法
while (scanf("%d",&n)!=EOF)
{
}
在控制台上用ctrl+Z 代表输入结束.
Source
Time Limit:1000MS Memory Limit:65536K
Total Submit:19 Accepted:6
Description
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有2个按钮:上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?
Input
有多组测试数据!对于每组测试数据第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。
Output
对于每组测试数据请输出一行,即最少按键次数,若无法到达,则输出-1。
Sample Input
5 1 5 3 3 1 2 5 10 1 10 8 1 2 3 4 5 6 7 8 9
Sample Output
3 -1
Hint
多组数据输入方法
while (scanf("%d",&n)!=EOF)
{
}
在控制台上用ctrl+Z 代表输入结束.
Source
/* 测试数据: 20 13 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */ /* ------------------------------------------------------------------------ 大概想法就是用动态规划来做。 1、描述最优子结构: 最少按键次数到达B层,必然也是最少按键次数通过n-1层,所以就产生了一个最优子 结构,动态规划适用。(还有什么重叠子问题的不是太懂) 2、递归定义最优解的值 由1可知,最少按键次数到达B层,必然也是最少按键次数通过n-1,同理也是最少按 键次数通过n-2..........递归定义...直到是否可以由A层到达以上符合条件的层数。 3.按自底向上的方式计算最优解的值 这里利用了两个二维数组,一个FNumTimes[203][3],[203]用来储存总共有多少层 [X][0]用来该层对应的上下层数字,[X][1]用来储存该层到达B层需要的最少按键次数 ,0表示,该层无法到达B层。[X][2]用来标志该层是否已经遍历过(如果没有这一个, 我的程序就会出错,因为这里可能会发生重复访问,比如最上面的一组测试数据)。 另外一个二维数组是用来TimesFNums[203][203],可以在该按键次数下,可以到达 目标楼层的楼层。前一维用来储存到达目标楼层需要的最少按键次数,分别是0次, 1次....200次,后一维用来储存在该最少按键次数可以到达目标楼层,对应的楼层数, 用于下一次迭代。 总之是先从B层开始出发,寻找能够按一次键就到达B层的有哪些楼层。然后第二轮再 从这些楼层出发,寻找能够按二次就到达这些楼层的有哪些楼层。。然后第三轮如此 递归。。直到对每一个子问题求解一次,计算出每一层到达B层需要的最少按键次数 4、由计算出的结果构造一个最优解 由于3已经计算出每一层的解,所以直接判断[X][1]是否等于0,是则无法到达,不是 则输入[X][1]的值。 ------------------------------------- 状态AC,0MS,440K,代码比较长,1.38K,这是我自己的弱点,总会将问题复杂化, 向比较复杂解法去想。所以,代码看起来比较乱。。逻辑不清啊~~~ ------------------------------------------------------------------------ */ #include<stdio.h> #include<memory.h> #include<math.h> int FNumsTimes[203][3] ; int TimesFNums[203][203] ; int main(void) { int N = 0 ; int A = 0 ; int B = 0 ; int nCounts = 0 ; int nThisTimes = 0 ; int i = 0 ; int j = 0 ; int k = 0 ; int n = 0 ; int fCanFind = 0 ; int fUnfinish = 1 ; while(scanf("%d%d%d",&N,&A,&B) != EOF) { memset(FNumsTimes,0,sizeof(FNumsTimes)) ; memset(TimesFNums,0,sizeof(TimesFNums)) ; for(i = 1 ; i <= N ; i++) { scanf("%d",&FNumsTimes[i][0]) ; } nCounts = 1 ; TimesFNums[0][0] = B ; fCanFind = 1 ; fUnfinish = 1 ; for(nThisTimes = 0 ; nThisTimes <= N ; nThisTimes++) { n = nCounts ; nCounts = 0 ; if(1 == fCanFind) { fCanFind = 0 ; for(i = 1 ; i <= N ; i++) { for(j = 0 ; j < n ; j++) { if(0 == FNumsTimes[i][2] && abs(i - TimesFNums[nThisTimes][j]) == FNumsTimes[i][0]) { FNumsTimes[i][2] = 1 ; TimesFNums[nThisTimes+1][nCounts] = i ; FNumsTimes[i][1] = nThisTimes + 1 ; nCounts++ ; if(i == A) { fUnfinish = 0 ; } fCanFind = fUnfinish ; } } } } } if(A == B) { printf("%d\n",0) ; } else if(0 == FNumsTimes[A][1]) { printf("%d\n",-1) ; } else { printf("%d\n",FNumsTimes[A][1]) ; } } return 0 ; }
#include<stdio.h> #include<memory.h> #include<math.h> int FNumsTimes[203][2] ; int TimesFNums[203][203] ; int main(void) { int N = 0 ; int A = 0 ; int B = 0 ; int nCounts = 0 ; int nThisTimes = 0 ; int i = 0 ; int j = 0 ; int k = 0 ; int n = 0 ; int fCanFind = 0 ; int fUnfinish = 1 ; while(scanf("%d%d%d",&N,&A,&B) != EOF) { memset(FNumsTimes,0,sizeof(FNumsTimes)) ; memset(TimesFNums,0,sizeof(TimesFNums)) ; for(i = 1 ; i <= N ; i++) { scanf("%d",&FNumsTimes[i][0]) ; } nCounts = 1 ; TimesFNums[0][0] = B ; fCanFind = 1 ; fUnfinish = 1 ; for(nThisTimes = 0 ; nThisTimes <= N ; nThisTimes++) { n = nCounts ; nCounts = 0 ; if(1 == fCanFind) { fCanFind = 0 ; for(i = 1 ; i <= N ; i++) { for(j = 0 ; j < n ; j++) { if(abs(i - TimesFNums[nThisTimes][j]) == FNumsTimes[i][0]) { TimesFNums[nThisTimes+1][nCounts] = i ; FNumsTimes[i][1] = nThisTimes + 1 ; nCounts++ ; if(i == A) { fUnfinish = 0 ; } fCanFind = fUnfinish ; } } } } } if(A == B) { printf("%d\n",0) ; } else if(0 == FNumsTimes[A][1]) { printf("%d\n",-1) ; } else { printf("%d\n",FNumsTimes[A][1]) ; } } return 0 ; }
相关文章推荐
- ACM-Giroro的地雷测试(AC,广度优先搜索)
- 奇怪的电梯(广度优先搜索)
- 洛谷Oj-奇怪的电梯-广度优先搜索
- 奇怪的电梯解题报告(广度优先搜索)
- 2833 奇怪的梦境 未AC
- 洛谷P1135 奇怪的电梯
- 洛谷Luogu-2759 奇怪的函数 (二分答案) HQG_AC的博客
- jzoj 1365. 【队列练习】奇怪的电梯
- [ACM]今年暑假不AC(贪心)
- HDU1548 奇怪的电梯 最短路 spfa bfs
- http://acm.nyist.net/JudgeOnline/problem.php?pid=527&&AC_mm玩dota
- ACM杭电的AC回顾——2025
- 杭电ACM1180——诡异的楼梯~~广度优先搜索
- ACM怀化学院交流赛总结之只有AC才有MM
- 杭电ACM 今年暑假不AC 2037(关于最简单的贪心算法)
- ACM 粗心永远AC不了系列——HDU 1754 I Hate It|线段树区间求最值
- 洛谷 P1135 奇怪的电梯 (搜索)
- 【DFS】奇怪的电梯
- [ACM]今年暑假不AC(贪心)
- ACM-游玩景点(AC,动态规划,最大子序列和问题)