乐视2017暑期实习生笔试编程题

前几天做了在乐视的笔试题,整体的来说的题目还是比较简单。前面的选择题都是比较普遍的一些关于操作系统、网络、linux等的题。后面有三道编程题得吐槽一下,虽然题不是很难,不涉及什么复杂的算法,但是题目介绍弄了一大堆的故事,看来几遍才弄懂了,特别是第一个题,少点套路就好了。

1.兵临城下

卢卡斯的驱逐者大军已经来到了赫柏的卡诺萨城,赫柏终于下定决心,集结了大军,与驱逐者全面开战。
卢卡斯的手下有6名天之驱逐者,这6名天之驱逐者各赋异能,是卢卡斯的主力。
为了击败卢卡斯,赫柏必须好好考虑如何安排自己的狂战士前去迎战。
狂战士的魔法与一些天之驱逐者的魔法属性是相克的,第i名狂战士的魔法可以克制的天之驱逐者的集合为Si(Si中的每个元素属于[0,5])。
为了公平,两名狂战士不能攻击同一个天之驱逐者。
现在赫柏需要知道共有多少种分派方案。
例:
S1={01},S2={23},代表编号为0的狂战士的魔法可以克制编号为0和编号为1的天之驱逐者,编号为1的狂战士的魔法可以克制编号为2和编号为3的天之驱逐者,共有四种方案:02,03,12,13。
02—代表第一个狂战士负责编号为0的驱逐者,第二个狂战士负责编号为2的驱逐者;
03—代表第一个狂战士负责编号为0的驱逐者,第二个狂战士负责编号为3的驱逐者;
12—代表第一个狂战士负责编号为1的驱逐者,第二个狂战士负责编号为2的驱逐者;
13—代表第一个狂战士负责编号为1的驱逐者,第二个狂战士负责编号为3的驱逐者;
S1={01},S2={01},代表编号为0的狂战士的魔法可以克制编号为0和编号为1的天之驱逐者,编号为1的狂战士的魔法可以克制编号为0和编号为1的天之驱逐者,共有两种方案:01,10。

输入描述:
多组测试数据,请处理到文件结束。

对于每组测试数据:

第一行为一个整数N,代表狂战士的数量。

第二行为N个字符串,第i个字符串表示第i个狂战士能够克制的天之驱逐者的集合。

保证:

1<=N<=6,1<=每个字符串的长度<=6,且每个字符都是0~5中的一个数字。

输出描述:
输出一个整数,代表分配方案数

输入例子:
2
01 23
2
01 01
3
3 015 5

解题代码
这道题就是普通的组合问题,每次从不同的集合里面取一个数,但是不能和前面取的重复,使用递归解决:

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Main{
    //保存所有的选择
    private static List<List<Character>> allPath=new LinkedList<List<Character>>();
    public static void main(String[] arg){
        Scanner in=new Scanner(System.in);
        while(in.hasNextLine()){
            int n=Integer.parseInt(in.nextLine());
            String str=in.nextLine();
            String[] s=str.split(" ");
            if(n==s.length){
                allPath.clear();
                LinkedList<Character> path=new LinkedList<>();
                CountNum(0,s,path);
                System.out.println(allPath.size());
            }
        }
        in.close();
    }   
    public static void CountNum(int index,String[] s,LinkedList<Character> path){
        //递归结束条件
        if(index==s.length){
            allPath.add(path);
            return;
        }
        String str=s[index];
        int len=str.length();
        for(int i=0;i<len;i++){
            char c=str.charAt(i);
            if(!path.contains(c)){
                path.add(c);
                //递归从下一个集合中选者
                CountNum(index+1,s,path);
                path.removeLast();
            }
        }
    }
}

2.幻兽交易

在最近几场魔兽争霸赛中,赫柏对自己的表现都不满意。
为了尽快提升战力,赫柏来到了雷鸣交易行并找到了幻兽师格丽,打算让格丽为自己的七阶幻兽升星。
经过漫长的等待以后,幻兽顺利升到了满星,赫柏很满意,打算给格丽一些小费。
赫柏给小费是有原则的:
1.最终给格丽的钱必须是5的倍数;
2.小费必须占最终支付费用的5%~10%之间(包含边界)。
升星总共耗费A魔卡,赫柏身上带了B魔卡,赫柏想知道他有多少种支付方案可供选择。
注:魔卡是一种货币单位,最终支付费用=本该支付的+小费

输入描述:
多组测试数据,请处理到文件结束。

对于每组测试数据:

包含两个整数A和B。

保证:

1<=A,B<=2,000,000,000,A<=B。

输出描述:
输出一个整数,代表方案数。

输入例子:
4 100
23 100

输出例子:
0
1

代码
这道题的难点在与时间复杂度,如果找到范围一个个遍历容易出现超时,所以只遍历5的倍数的就行了。

import java.util.Scanner;
public class Main{

    public static void main(String[] arg){
        Scanner in=new Scanner(System.in);
        while(in.hasNext()){
            int a=in.nextInt();
            int b=in.nextInt();
            System.out.println(countNum(a,b));
        }
        in.close();
    }   
    public static int countNum(int a,int b){
        int count=0;
        //找到范围,主要如何取值
        int start=(int)Math.ceil(a/0.95); 
        int end=(int)Math.floor(a/0.9);
        //找到第一个5的倍数
        while(start%5!=0 && start<end){
            start++;
        }
        for(int i=start;i<=end && i<=b;i=i+5){
                    count++;
        }
        return count;
    }
}

3.禁忌雷炎

赫柏在绝域之门击败鲁卡斯后,从鲁卡斯身上掉落了一本高级技能书,赫柏打开后惊喜地发现这是一个早已失传的上古技能—禁忌雷炎。
该技能每次发动只需扣很少的精神值,而且输出也非常高。
具体魔法描述如下:
把地图抽象为一个二维坐标,技能发动者位于(0,0)位置。以技能发动者为中心,做一个半径为r的圆,满足r^2=S,如果敌人位于这个圆上,且位置为整点坐标,这个敌人将收到该技能的输出伤害。。
例如当S=25时,将有12个敌人受到该技能的输出伤害,如下图所示:
这里写图片描述

更厉害的是,禁忌雷炎可以通过改变魔法输入来控制S的大小,因此数学好的魔法师可以通过该技能攻击到更多的敌人。
赫柏想将这个技能学会并成为自己的主技能,可数学是他的硬伤,所以他请求你为他写一个程序,帮帮他吧,没准他就把禁忌雷炎与你分享了 : )

输入描述:
多组测试数据,请处理到文件结束。

对于每组测试数据,只包含一个整数S。

保证:

1<=S<=2,000,000,000。

输出描述:
输出一个整数,代表受到禁忌雷炎伤害的敌人数量。

输入例子:
25
3

输出例子:
12
0
代码
这道题也是时间复杂度的问题,只用求一个角再乘以4就可以了,但要主要x,y轴上的点不要重复求。

import java.util.Scanner;
public class Main3{

    public static void main(String[] arg){
        Scanner in=new Scanner(System.in);
        while(in.hasNext()){
            int s=in.nextInt();
            System.out.println(countNum(s));
        }
        in.close();
    }   
    public static int countNum(int s){
        int count=0;
        int r=(int)Math.sqrt(s);
        //遍历,避免重复求解
        for(int i=1;i<=r;i++){
            //在到x=i时,y值是不是整数就行了。
            int m=s-i*i;
            int n=(int) Math.sqrt(m);
            if(n*n==m)
                count++;
        }
        return count*4;
    }
}

虽然这些题都过了测试用例,但是时间仓促,可能还存在问题,仅供参考。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值