腾讯2019秋招笔试真题 1.小Q爬塔 2.妞妞的问题

1.小Q爬塔

【问题描述】小Q正在攀爬一座宝塔,这座宝塔很特别,塔总共有n层,但是两层之间的净高却不相同,所以造成小Q爬过每层的时间也不同。如果某一次高度为x,那么爬过这一层所需时间也就是x。小Q还会使用一种魔法每使用一次可以让他向上跳1层或者两层,但是每次跳后,必须至少爬一层才能接着使用魔法。(你可以认为小Q需要跳两次一层才休息,最后也可以跳到塔外即超过塔高,跳事不消耗时间的)小Q想用最短的时间上顶,希望你能告诉他最短时间是多少?

输入描述:
第一行一个数n(n<=10000),表示从下往上每层的高度。
接下来的n行每行一个数h(1<=h<=100),表示从下往上每层的高度。
输出描述:
一个数,表示最短时间
输入样例:
5
3
5
1
8
4
输出样例:
1

解题思路:
p[i]表示到达第i层最短时间,并且到达第i层方式是
t[i]表示到达第i层最短时间,并且到达第i层方式是
考虑到达第i层的方式采用爬还是跳。

  • 情况1 到达第i层的方式是爬:
    那么到达第i-1层的方式可以是跳,也可以是爬,二者选一
    p[i] = min(p[i-1],t[i-1])+a[i]
  • 情况2 到达第i层的方式是跳:
    那么可以从第i-1层起跳,也可以从i-2层起跳,并且到达i-1层和i-2层的方式只能是爬,所以二者选最小的
    t[i] = min(p[i-1],p[i-2])

最终在p[n]和t[n]中选择最小值做结果

代码:

	public static void main(String[] args) {
        // 构建p和t数组存储最短时间
        int []p=new int[10005];
        int []t=new int[10005];
        Scanner sc=new Scanner(System.in);
        // 塔的高度为层
        int n=sc.nextInt();
        // 构建塔数组
        int []a=new int[n];
        int count=0;
        while (count<n){
            a[count++]=sc.nextInt();
        }
        // i代表第几层 a[i-1]代表从上一层到现在层的高度
        for (int i=1;i<=n;i++){
            // 第i层是爬上来的
            p[i]=Math.min(p[i-1],t[i-1])+a[i-1];
            // 第i层是跳上来的
            if (i>=2)
            t[i]=Math.min(p[i-1],p[i-2]);
        }
        System.out.println(Math.min(p[n],t[n]));
    }

2.妞妞的问题

【题目描述】
妞妞公主新得到一块白色棋盘。这块棋盘共有n行m列,任意相邻的两个格子都是不同的颜色(黑或白),坐标位(1,1)的格子是白色的。

这一天牛牛来看妞妞公主时,牛牛公主正望着棋盘发呆。牛牛看妞妞公主闷闷不乐的样子,便对妞妞公主说:“只要你告诉我n和m,我能马上算出黑色方块的白色方块的数量。”

“这太简单了。”妞妞公主想了一会,“我会在这n行m列中选择一个左下角坐标位(x0,y0)。右上角坐标为(x1,y1)的矩形,把这个矩形里的共(x1-x0+1)*(y1-y0+1)个方块全部涂白。你还能马上算出黑色方块和白色方块的数量吗?”

“这太简单了。”牛牛自信一笑,“你还可以在执行涂白操作后再选择一个左下角坐标为(x2,y2),右上角坐标为(x3,y3)的矩形,把这个矩形里的方块全部涂黑。我依然能马上算出黑色方块和白色方块的数量。”

妞妞公主终于惊讶地睁大了眼睛,于是抛出了她的T次提问。

聪明的牛牛当然会做了,但是他想把这个问题交给你,请帮牛牛算出每次提问棋盘的黑白方块数目吧。

输入描述:
第一行一个整数T,表示妞妞公主一共提问了T次。
接下来3T行,
第(1+3i)行两个整数n,m。表示第i次提问时棋盘的大小;
第(2+3i)行四个整数x0,x1,y0,y1。表示第i次提问时涂白操作选取的两个坐标。
第(3+3i)行四个整数x2,y2,x3,y3。表示第i次提问时涂黑操作选取的两个坐标。
1<=T<=10000,1<=x<=n<=1000000000,1<=y<=m<=1000000000,x0<=x1,y0<=y1,x2<=x3,y2<=y。

输出描述:
共T行,每行两个整数分别表示白色方块的数量和黑色方块的数量。

详细解答可参考:https://blog.csdn.net/lx8486/article/details/92974201
代码:

	// n行m列,x,y数组代表4个矩形点坐标的x,y位置
    public static int[] nums(int n,int m,int[] x,int[] y){
        // 返回值,res[0]白方块的数量,res[1]为黑的
        int[] res = new int[2];
        // 当总方块数是偶数,黑白各一半
        int black = n * m / 2;
        // 为奇数时,白方块多一个
        int white = n * m - black;
        int a,b,c,d,e;

        // 1.第一步将(x0,y0),(x1,y1)矩形内的方块都涂白,也就是计算出黑方块的个数d(将白方块个数+d,黑方块-d)
        // x,y坐标位置和为奇数,则起始位置是黑方块
        if(((x[0] + y[0]) & 1) == 1)
            // 如果矩形中方块数为奇数,则黑方块多一个
            d = ((x[1] - x[0] + 1) * (y[1] - y[0] + 1) + 1) / 2;
        else
            // 否则,黑白个数一样
            d = ((x[1] - x[0] + 1) * (y[1] - y[0] + 1)) / 2;
        white += d;
        black -= d;

        // 2.第二步将(x2,y2),(x3,y3)矩形内的方块都涂黑,也就是计算出白方块的个数d (将白方块个数-d,黑方块+d)
        // x,y坐标位置和为奇数,则起始位置是黑方块
        if(((x[2] + y[2]) & 1) == 0)
            // 如果矩形中方块数为奇数,则白方块多一个
            d = ((x[3] - x[2] + 1) * (y[3] - y[2] + 1) + 1) / 2;
        else
            // 否则,白黑个数一样
            d = ((x[3] - x[2] + 1) * (y[3] - y[2] + 1)) / 2;
        white -= d;
        black += d;

        // 第三步,找到两个矩形的公共部分,该部分中在第一步将所有方块涂白了,
        // 而第二步计算依然按照没涂白之前的计算,也就是少算了第一步之前的黑方块个数
        // 也就是第一步多计算的白方块e,
        // 最后白方块个数-e,黑方块个数+e
        a = Math.max(x[0],x[2]);
        b = Math.max(y[0],y[2]);
        c = Math.min(x[1],x[3]);
        d = Math.min(y[1],y[3]);
        if(c < a || d < b)//没有公共部分
            e = 0;
        else{
            if(((a + b) & 1) == 1)// x,y坐标位置和为奇数,则起始位置是黑方块
                // 如果矩形中方块数为奇数,则黑方块多一个
                e = ((c - a + 1) * (d - b + 1) + 1) / 2;
            else
                // 否则,黑白个数一样
                e = ((c - a + 1) * (d - b + 1)) / 2;
        }
        white -= e;
        black += e;
        res[0] = white;
        res[1] = black;
        return res;
    }

    public static void main(String[] args) {
        int times = 3;
        int[] n = new int[]{1,3,3};
        int[] m = new int[]{3,3,4};
        int[][][] xAndY = new int[][][]{{{1,1,1,1},{1,3,1,3}},{{1,2,2,3},{1,3,1,3}},
                {{2,2,1,3},{1,3,2,3}}};
        for (int i = 0;i < times;i++){
            int[] res = nums(n[i],m[i],xAndY[i][0],xAndY[i][1]);
            System.out.println(res[0]+","+res[1]);
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值