前几天做了在乐视的笔试题,整体的来说的题目还是比较简单。前面的选择题都是比较普遍的一些关于操作系统、网络、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;
}
}
虽然这些题都过了测试用例,但是时间仓促,可能还存在问题,仅供参考。