您的位置:首页 > 其它

顺丰科技2018校园招聘在线笔试题

2017-09-20 22:39 369 查看

今天做了顺丰科技的在线笔试题,选择题方面感觉考得很基础,有数据结构、编译原理方面的题目,以及设计模式的题目。编译原理的内容基本忘记了,设计模式也没有进行深入的学习,所以这两块大的并不是太好。再有就是排序算法,出现了两道排序算法思想的问题:一个是给一个序列,指明使用的排序算法,写出经过两趟排序后的序列;另一个是给出原序列和n次排序后的序列,指出使用的排序算法。另外,对常见的排序算法的稳定性、时间复杂度的考察也涉及到了。

好了废话不多说,进入今天的正题吧:两道算法题的解决思路课编码实现

第一题:

题目描述:

木木一不小心不记得电脑的锁屏密码了,木木很着急,所以找到安安来解决,因为密码是安安帮木木设置的。

设木木的密码为B数列,安安的密码为A数列,A,B数列的长度都为n,并满足以下条件:

对于安安密码中的第i个数Ai ,有:Ai = Bi − Bi+1  + Bi+2 − Bi+3....

现在,知道安安的密码,即A数列,求木木的密码。

输入

第一行输入一个整数n,(2 ≤ n ≤ 100 000) ,代表密码的长度。

接下来n行,每行输入一个整数Ai,(按下标字典序输入)代表安安的密码,即A数列( -109 ≤ Ai≤ 109)。

输出

输出n行,每行一个整数,(按下标字典序输出)代表木木的密码,即B数列。

样例输入

5

3

-2

-1

5

6

样例输出

1

-3

4

11

6

题目给出了代码框架,我们只需要实现解决的方法solve();其实拿到题目第一眼会感觉比较复杂,又是加密又是数学表达式,很能唬人。但是经过深入的分析发现其实式子时可以整理的,整理后其实就是Bi={Ai+Ai+1,Ai,if i<n if i=n

这样就容易编码为:

static int[] solve(int[] a) {
int [] res = new int[a.length];
//不用递归是因为递归的时间和空间复杂度较非递归大
for (int i = 0; i < res.length; i++) {
if(i != res.length - 1 )
res[i] = a[i]+a[i+1];
else
res[i] = a[i];
}
return res;
}


第二题:题目忘记copy了,凭记忆写吧

大致意思是给定一个数n求小于等于n的“幸运数字”。幸运数字的定义:这个数只由4或者7组成,那么称此数字为幸运数字。

另外由于输出可能很大,所以输出的结果为幸运数字的个数除以108+7还是多少…记得不太清了

样例输入:

125

输出:

6

这里给出我的解决思路和代码,由于测试的时候有一个函数没能实现完成,所以没有全部AC。在结束测试后实现了该部分代码,自己进行测试可以通过,但是不知道在系统中会不会超时或者超出内存。

解决思路:

通过观察规律
b9e4


0-10之内的数中,幸运数的个数是4、7即有两个

10-100之内的数中,幸运数的个数是44、47、74、77既有四个





以此类推,我们不难发现n位数内的幸运数个数是2的n次排列组合即2n个,那么可以根据输入的数字的位数n,先得到n-1位数以下有多少个幸运数,然后加上从最小的n位数即(444…)开始到n之间的幸运数个数。

到这里,我们可以容易得到n位数中最小的幸运数是444…4,最大的幸运数是777…7,那么我么可以分情况讨论:

当输入的数字小于444..44那么结果就是n-1位数以下幸运数的个数;当输入的数字大于等于777…7那么结果就是n位数下的幸运数个数;当输入的数在444…4到777…7之间那么就需要运算从444…4到n之间的幸运数个数了。

理清了思路就可以开始编码了:

整体代码应该比较好理解

package timu2;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.print(getLuckyNumCount(n));
}

//获得幸运数字的个数
private static int getLuckyNumCount(int n) {
int numLength = getLength(n);
int count = numLength;
int result = 0;
int minLuckNum = getMinLuckNum(numLength);
int maxLuckNum = getMaxLuckNum(numLength);

if (n == minLuckNum) {
while (count > 1) {
result += Math.pow(2, count - 1);
count--;
}
result += 1;
} else if (n < minLuckNum) {
while (count > 1) {
result += Math.pow(2, count - 1);
count--;
}
} else if (n >= maxLuckNum) {
while (count >= 1) {
result += Math.pow(2, count);
count--;
}
} else if (n > minLuckNum && n < maxLuckNum) {
while (count > 1) {
result += Math.pow(2, count - 1);
count--;
}
result += getCount(n, numLength);
}
return result % (1000000000 + 7);
}

//获得444..4到输入的数字n之间的幸运数字的个数
private static int getCount(int n, int numLength) {
int result = 0;
for (int i = 444; i <= n; i++) {
if (isLuckNum(i)) {
result++;
}
}
return result;
}

//判断是否为幸运数字
private static boolean isLuckNum(int i) {
String str = i + "";
char[] chs = str.toCharArray();
int a = 0;
int b = chs.length;
for (int j = 0; j < chs.length; j++) {
if ((chs[j]+"").matches("4|7"))
a++;
}
return b == a;

}

//获得n位数中最小的幸运数字
private static int getMinLuckNum(int numLength) {
StringBuilder sb = new StringBuilder();
while (numLength-- > 0) {
sb.append("4");
}
// System.out.println(sb);
return Integer.parseInt(sb.toString());
}

//获得n位数最大的幸运数字
private static int getMaxLuckNum(int numLength) {
StringBuilder sb = new StringBuilder();
while (numLength-- > 0) {
sb.append("7");
}
// System.out.println(sb);
return Integer.parseInt(sb.toString());
}

//得到数字的位数
private static int getLength(int n) {
return ("" + n).length();
}
}


以上就是我自己在做顺丰科技的笔试题的时候的思路和编码,也许不是最优解,也欢迎大家来批评指正~

这几天被各大公司的笔试题编程题轮番虐,有点怀疑人生了…不过只要没有停止学习,相信一切都会好的。找工作,继续加油!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: