title: 研二面试题目
date: 2019-10-1 12:03:55
updated: 2020-03-11 21:36:57
categories: 算法刷题
tags:
- 算法刷题
- 面经
本博文本意想记录研二春招实习、秋招找工作阶段经历过的几家面试题目,但最后时间和精力不允许,并没有保存,就把360的面经当成这段时光的纪念吧
360春招三道编程题
1.分金子
题目:A、B两伙马贼意外地在一片沙漠中发现了一处金矿,双方都想独占金矿,但各自的实力都不足以吞下对方,经过谈判后,双方同意用一个公平的方式来处理这片金矿。处理的规则如下:他们把整个金矿分成n段,由A、B开始轮流从最左端或最右端占据一段,直到分完为止。
马贼A想提前知道他们能分到多少金子,因此请你帮忙计算他们最后各自拥有多少金子?(两伙马贼均会采取对己方有利的策略)
具体的看 原题及解析连接
思路:动态规划dp[][]。dp[i][j] = sum[j]-sum[i-1]-Math.min(dp[i+1][j],dp[i][j-1]);
import java.io.*;
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner cin = new Scanner(System.in);
int t = cin.nextInt();
for(int times=1; times<=t;++times){
int k = cin.nextInt();
int[] nums = new int[k];
for(int i=0; i<k; ++i){
nums[i] = cin.nextInt();
}
int[] res = compute(nums, k);
System.out.printf("Case #%d: %d %d\n", times, res[0], res[1]);
}
}
public static int[] compute(int[] nums, int n){
int[][] dp = new int[n+1][n+1];
int[] sum = new int[n+1];
for(int i=1; i<=n; ++i){
dp[i][i] = nums[i-1];
sum[i] = sum[i-1] + nums[i-1];
}
for(int i=n-1; i>0; --i){
for(int j=i+1; j<=n; ++j){
dp[i][j] = sum[j]-sum[i-1]-Math.min(dp[i+1][j],dp[i][j-1]);
}
}
return new int[]{dp[1][n], sum[n]-dp[1][n]};
}
}
2.剪气球串
题目:本题题意可以抽象成一个数学的表述,即一个长度为n的数组,每一个数的范围是1到9,现在我们需要将这个数组分成多个连续子数组,保证每个子数组内数字均不相同,问一共有多少种满足要求的分法。
具体的看 原题及解析连接
思路:这题需要用到动态规划进行求解,我们不妨记一个数组dp[i],表示这个数组前i个数组成的数组可以有多少种分法,数组初始全为0,特别的dp[0]初始为1。那么在计算dp[i+1]时,我们需要考虑第i+1个数可以和前面哪些数分到一起组成连续的子数组,比如第i+1个数可以和第i个数组成一组,但不能和第i-1个数分到一组,那么dp[i+1]=dp[i]+dp[i-1]
import java.io.*;
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner cin = new Scanner(System.in);
while(cin.hasNext()){
int n = cin.nextInt();
int[] nums = new int[n];
for(int i=0; i<n; ++i){
nums[i] = cin.nextInt();
}
int[] dp = new int[n+1];
dp[0] = 1;
for(int i=1; i<=n; ++i){
int[] cnt = new int[10];
for(int j=i-1; j>=0; j--){
cnt[nums[j]]++;
if(cnt[nums[j]]>1){
break;
}
dp[i] = (dp[i] + dp[j])%1000000007;
}
}
System.out.println(dp[n]);
}
}
}
3.跑步
题目:小明同学喜欢体育锻炼,他常常去操场上跑步。跑道是一个圆形,在本题中,我们认为跑道是一个半径为R的圆形,设圆心的坐标为原点(0,0)。
小明跑步的起点坐标为(R,0),他沿着圆形跑道跑步,而且一直沿着一个方向跑步。回到家后,他查看了自己的计步器,计步器显示他跑步的总路程为L。
小明想知道自己结束跑步时的坐标,但是他忘记自己是沿着顺时针方向还是逆时针方向跑的了。他想知道在这两种情况下的答案分别是多少。
具体的看 原题及解析连接
思路:根据跑步总长L,先计算绕着圆心转动角度θ=L/r,之后顺时针x=cosθ*r,y=-sinθ*r,逆时针同理。
import java.io.*;
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner cin = new Scanner(System.in);
int l, r;
l = cin.nextInt();
r = cin.nextInt();
double threta = l*1.0/r;
System.out.printf( "%.3f %.3f\n", (Math.cos(threta)*r), (-Math.sin(threta)*r));
System.out.printf( "%.3f %.3f\n", (Math.cos(threta)*r), (Math.sin(threta)*r));
}
}