是男人就下100层

相信大家都听说过“是男人就下100层”系列游戏,游戏中包括多个长度和高度各不相同的平台,地面是最低的平台,高度为零,长度无限。
一个男人在开始的时候从高于所有平台的某处开始下落,它的下落速度始终为1米/秒。当他落到某个平台上时,游戏者选择让他向左或向右跑,跑动的速度也是1米/秒。当他跑到平台的边缘时会继续下落。要求每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。

请帮忙设计一个程序,计算最快到达地面所用的时间。

import java.util.*;
 
public class Main {
 
    public static void main(String[] args) {
        @SuppressWarnings("resource")
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            Integer[][] floors = new Integer[in.nextInt()][3];
            int X = in.nextInt(), Y = in.nextInt(), MAX = in.nextInt();
            int left = Integer.MAX_VALUE, right = Integer.MIN_VALUE;
            for (int i = 0; i < floors.length; i++) {
                int temp = in.nextInt();
                left = Math.min(left, temp);
                floors[i][0] = temp;
                temp = in.nextInt();
                right = Math.max(right, temp);
                floors[i][1] = temp;
                floors[i][2] = in.nextInt();
            }
            System.out.println(calc(floors, X, Y, MAX, left, right));
        }
    }
 
    static int calc(Integer[][] floors, int X, int Y, int MAX, int left, int right) {
        // 横坐标对齐
        for (int i = 0; i < floors.length; i++) {
            floors[i][0] -= left;
            floors[i][1] -= left;
        }
        X -= left;
        right -= left;
        left = 0;
 
        // 将平台按高度排序,同高度则按横坐标排序
        Arrays.sort(floors, new Comparator<Integer[]>() {
            @Override
            public int compare(Integer[] arg0, Integer[] arg1) {
                if (arg0[2].equals(arg1[2]))
                    return arg0[0] - arg1[0];
                return arg0[2] - arg1[2];
            }
        });
 
        // 如果X不在平台横纵坐标范围,直接掉下来即可(不考虑无解及非法情况)
        if (X < 0 || X > right || Y < floors[0][2])
            return Y;
 
        // dp求解,第一个值表示到达地面最小时间,第二个值表示当前往下跳的高度
        int[][] dp = new int[right + 1][2];
        int low = 0, high = floors[0][2];
        for (Integer[] floor : floors) {
 
            // 判断进入新的一层
            if (high < floor[2]) {
                // 上一层右边空档区
                int det = high - low;
                for (int i = left; i <= right; i++) {
                    dp[i][0] += det;
                    dp[i][1] += det;
                }
                // 平台高于Y值,舍弃(测试用例中貌似没有用到)
                if (high > Y) {
                    high = low;
                    break;
                }
                // low、high上升一层
                low = high;
                high = floor[2];
                left = 0;
            }
            int det = high - low;
            // 左边空挡区
            for (int i = left; i < floor[0]; i++) {
                dp[i][0] += det;
                dp[i][1] += det;
            }
            // 中间平台区,判断从左边、右边能否走通
            boolean isLeft = dp[floor[0]][1] + det <= MAX;
            boolean isRight = dp[floor[1]][1] + det <= MAX;
            for (int i = floor[0]; i <= floor[1]; i++) {
                if (!isLeft && !isRight) {
                    dp[i][1] = MAX + 1;
                    continue;
                }
                int goRight = floor[1] - i + dp[floor[1]][0] + det;
                // left取的是新值,只有最左边的需要+det
                int goLeft = i - floor[0] + dp[floor[0]][0];
                if (i == floor[0])
                    goLeft += det;
                if (!isLeft)
                    dp[i][0] = goRight;
                else if (!isRight)
                    dp[i][0] = goLeft;
                else
                    dp[i][0] = Math.min(goLeft, goRight);
                dp[i][1] = 0;
            }
            // left指针右移
            left = floor[1] + 1;
        }
        return dp[X][0] + Y - high;
    }
 
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
男人就下100游戏源码,经典的flash游戏《是男人就下100》登录win8平台了,支持surface 以及 surface pro, 操作方式支持键盘左右键和触摸操作,该游戏现在android版,ios版已经上线了,但是wp版现在才开发的,喜欢的朋友可以了解一下吧。 项目介绍 这毕竟是个小游戏,本身其实没有什么技术难点,主要在于项目的设计,分为如下几个小模块 1、玩家 (Player) 玩家类我用了单例模式,继承自CCSprite,因为贯穿游戏一直会有玩家存在,在这个版本里也不会有第二个,所以单例成了我很好的选择。 封装了 运动、血量 等。整体的游戏运动采取了背景运动而人不动的方式,感觉在这里这种要更容易掌控一些,分很明显。 2、平台 这里我参照了 Floyd 的Js版本实现,以 BlockBase 作为所有平台游戏的基类,实现了向上运动,检测玩家碰撞,移除平台等基础功能。 然后根据不同的平台类型,继承该基类实现不同效果,比如跳起,伤害,左右平移等。 分别有:NormalBlock (最普通的平台) 、FlipBlock(让人弹跳的平台)、MissBlock(会破损的平台)、ThornBlock(带刺的平台)、LeftRunBlock、RightRunBlock (左右运动的平台) 还有个 BlockFactory 工厂类, 负责在恰当的时候创建合适的平台,创建的规则是随机类型,位置是从预先定义的几个里面随机取。 对于所有平台的管理, 本来最好应该是做个缓存池的,但是我发现这个性能降低实在是可以忽略,所以。。。 3、输入 输入这里,定义了一个基类,InputBase,因为最终肯定有几种输入的方式:PC(键盘、鼠标)、手势、重力感应等,所以这个从一开始就要考虑到。具体的处理方式是 给定一个固定的运动速度, 然后有输入事件的时候就让玩家按照这个速度来运行, 但是现在实际的效果感觉还不太理想。 4、场景 场景就是那么基础的几个了。。。游戏主界面采用了MVC的模式来设计,CCScene 作为 Controller ,其它的Layer 作为View。其它页面都比较简单,单Layer 实现。逻辑也都放在Layer里了。 另外,专门定义了一个 HideLayer ,目的是实现弹出对话框的效果,考虑到原场景中可能会有CCMenu,我将该 Layer 的 优先级设为了 与 CCMenu 相同,因为后添加的原因,所以总能屏蔽 Menu 的事件, 而且在 Layer 上再添加Menu 也不会有问题。 还有个比较有意思的是: 所有的场景我都继承了 IBackableScene 接口,这是我自己定义的一个抽象类,因为我发现对于 “后退” 按钮的处理在游戏中是非常常见的,所以这个接口里定义了 bool GoBack() = 0 函数, 所有需要响应后退事件的场景都要实现该方法,然后在该方法里实现具体的返回 代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值