研二面试题目

本文记录了360公司在春季招聘中提出的三道编程题目,包括分金子问题、剪气球串问题和跑步问题。每道题目都提供了思路概述,并链接到原题及解析,涉及动态规划等算法知识。
摘要由CSDN通过智能技术生成

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));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值