【2022-09-14】携程秋招笔试四道编程题

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经,目前已更新至美团、微软…
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

第一题:切披萨

题目描述

游游拿到了一个边长为n的正方形披萨,她准备切k刀(每刀只能横着或竖着切开),最终会形成若干个小矩形披萨。

游游希望每个小披萨的面积相等,且矩形的长和宽的差的绝对值尽可能小。你能帮游游求出每个小矩形的面积吗?

输入描述

两个正整数n和k,用空格隔开。1<n,k<100

2 1

输出描述

一个浮点数,代表每个小矩形的面积,小数点后保留2位。

2.00

思路

要求切出来的矩形面积都相等,均匀切即可。

代码

Java版本
import java.util.Scanner;

public class first {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(),k = sc.nextInt();
        double v = n+0D;
        if(k==1){
            System.out.printf("%.2f%n",v*v/2);
            return;
        }
        int x = k>>1;
        int y = k-x;
        double res = (v*v)/((x+1)*(y+1));
        System.out.printf("%.2f%n",res);
    }

}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
n, k = map(int, input().split())
if k == 1:
    print('%.2f' % (n * n / 2))
else:
    m = k // 2
    a = n / (m + 1)
    b = n / (k - m + 1)
    print('%.2f' % (a * b))
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>

using namespace std;

int main() {
  int n, k;
  cin >> n >> k;

  float s = 0.0;
  if (k % 2 == 0) {
    float parts = k / 2 + 1;
    s = n / parts * n / parts;
  }
  else {
    float partsw = (k - 1) / 2 + 1;
    float partsl = (k + 1) / 2 + 1;
    s = n * n / (partsw * partsl);
  }
  printf("%0.2f", s);

  return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递

第二题:01矩阵

题目描述

游游拿到了一个2行2列的01矩阵a,她每次操作可以交换a的相邻两个元素(同一行或者同一列均为相邻)。

游游想知道至少要多少次操作可以使得矩阵a变成矩阵b?

输入描述

共有t组询问。第一行输入一个正整数t<100,代表询问的次数。

每组询问共有4行,每行两个正整数。前两行用来表示矩阵a,后两行用来表示矩阵b。

2
0 1
1 0
1 0
0 1
0 0
0 0
1 1
1 1

输出描述

输出t行,每行输出一行答案。

如果无论如何都不能使得矩阵a变成矩阵b,则输出-1。

否则输出一个整数,代表操作的最小次数。

2
-1

思路

矩阵位置设为0,1,2,3
如果两个矩阵不同的位置为0个,答案为0
如果两个矩阵不同的位置为4个,答案为2
如果两个矩阵不同的位置为2个,
当为0、3或者1、2时,答案为2,
其余情况答案为1

代码

Java版本
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class second {
    static int[][] dist = {{-1,0},{1,0},{0,-1},{0,1}};
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int t = sc.nextInt();
        for (int i = 0; i < t; i++) {
            int[][] a = new int[][]{{sc.nextInt(),sc.nextInt()},{sc.nextInt(),sc.nextInt()}};
            int[][] b = new int[][]{{sc.nextInt(),sc.nextInt()},{sc.nextInt(),sc.nextInt()}};
            if(cout(a)!=cout(b)){
                bw.write("-1");
                continue;
            }
            int time = Integer.MAX_VALUE>>1;
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 2; k++) {
                    time = Math.min(getTime(a, b,j,k),time);
                }
            }
            if(time>=Integer.MAX_VALUE>>1)
                bw.write("-1");
            else
                bw.write(Integer.toString(time));
            if(i<t-1) bw.newLine();
        }
        bw.flush();
    }

    private static int cout(int[][] b) {
        int res = 0;
        for (int[] ints : b) {
            for (int anInt : ints) {
                if(anInt==1)res++;
            }
        }
        return res;
    }

    private static int getTime(int[][] a, int[][] b, int x, int y) {
        if(isVaild(a,b))
            return 0;
        if(x<0||x>=2||y<0||y>=2)
            return Integer.MAX_VALUE>>1;
        int res = Integer.MAX_VALUE>>1;
        for (int[] ints : dist) {
            swap(x,y,x+ints[0],y+ints[1],a);
            res = Math.min(res,getTime(a,b,(y==1?x+1:x),(y==1?0:y+1))+1);
            swap(x,y,x+ints[0],y+ints[1],a);
        }
        return res;
    }

    private static void swap(int x, int y, int x1, int y1, int[][] a) {
        if(x1<0||x1>1||y1<0||y1>1)return;
        int k = a[x][y];
        a[x][y] = a[x1][y1];
        a[x1][y1] = k;
    }


    private static boolean isVaild(int[][] a, int[][] b) {
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++) {
                if(a[i][j]!=b[i][j])
                    return false;
            }
        }
        return true;
    }
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
from collections import deque


def trans(m):
    return m[0][0] * 1000 + m[0][1] * 100 + m[1][0] * 10 + m[1][1]


for _ in range(int(input())):
    a = [list(map(int, input().split())), list(map(int, input().split()))]
    b = [list(map(int, input().split())), list(map(int, input().split()))]
    target = trans(b)
    ans = -1
    q = deque()
    q.append((0, a))
    seen = set([trans(a)])
    while q:
        price, m = q.popleft()
        if trans(m) == target:
            ans = price
            break
        nxts = [
            [
                [m[0][1], m[0][0]],
                m[1]
            ],
            [
                m[0],
                [m[1][1], m[1][0]]
            ],
            [
                [m[1][0], m[0][1]],
                [m[0][0], m[1][1]]
            ],
            [
                [m[0][0], m[1][1]],
                [m[1][0], m[0][1]]
            ]

        ]
        for nxt in nxts:
            v = trans(nxt)
            if v not in seen:
                q.append((price + 1, nxt))
                seen.add(v)
    print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>

using namespace std;

int main() {
  int t;
  cin >> t;
  for (int i = 0; i < t; i++) {
    vector<int> mata(4), matb(4);
    for (int j = 0; j < 4; j++)
      cin >> mata[j];
    for (int j = 0; j < 4; j++)
      cin >> matb[j];
    int check = 0;
    for (int j = 0; j < 4; j++) {
      if ((mata[j] != 0 && mata[j] != 1) || (matb[j] != 0 && matb[j] != 1)) {
        check = 1;
        break;
      }
    }
    if (check) {
      cout << "-1" << endl;
      continue;
    }
    int na1 = 0, nb1 = 0;
    for (int j = 0; j < 4; j++) {
      if (mata[j] == 1)
        na1++;
      if (matb[j] == 1)
        nb1++;
    }

    if (na1 != nb1) {
      cout << "-1" << endl;
      continue;
    }

    if (na1 == 0 || na1 == 4) {
      cout << "0" << endl;
      continue;
    }

    vector<int> matemp(4);
    int sum = 0;
    for (int j = 0; j < 4; j++) {
      matemp[j] = abs(mata[j] - matb[j]);
      sum += matemp[j];
    }
    if (sum == 0) {
      cout << "0" << endl;
    }
    else if ((matemp[0] == 1 && matemp[3] == 1) || (matemp[1] == 1 && matemp[2] == 1)) {
      cout << "2" << endl;
      continue;
    }
    else {
      cout << "1" << endl;
      continue;
    }
  }

  return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递

第三题:数字染色

题目描述

游游拿到的一个数组,其中一些数被染成红色,另一些数被染成蓝色。

游游每次操作,可以使得所有红色的数加1,或者可以使得所有蓝色的数减1。一共可以操作任意次。

游游希望最终数组的最大值减去最小值的差尽可能小,你能帮她求出这个差吗?

输入描述

输入包含多组测试用例,第一行一个正整数t,表示测试用例组数。

每组测试用例的第一行输入一个正整数n,代表数组的长度。

第二行输入n个正整数ai,代表游游拿到的数组。

第三行输入一个长度为n的、仅由’R’和’B’两种字符组成字符串,第i个字符为’R’代表第i个数染成红色,为‘B’代表染成蓝色。

1<n<2e3

1 < ai < 1e9

保证所有测试用例的n的总和不超过2e5

1
5
1 2 3 4 5
RRBRB

输出描述

3

说明:对红色的数和蓝色的数各操作一次,数组变成[2,3,2, 5,4],此时数组的最大值减最小值等于3。可以证明这个差无法小于3。

思路

贪心。因为红色值只能向上,蓝色值只能向下,只需要维护红色最大值最小值和蓝色最大值最小值。比如红色最大值更大的时候说明没有必要对红色进行操作,蓝色最小值最小的时候就没有必要对蓝色操作。否则要看将红色对齐到蓝色的代价和将蓝色对齐到红色的代价。

Java版本
public class fourth {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int t = Integer.parseInt(br.readLine());
        for (int i = 0; i < t; i++) {
            int n = Integer.parseInt(br.readLine());
            String[] arr = br.readLine().split(" ");
            String s = br.readLine();
            int rmax = 0,rmin = Integer.MAX_VALUE;
            int bmax = 0,bmin = Integer.MAX_VALUE;
            for (int j = 0; j < n; j++) {
                if(s.charAt(j)=='R'){
                    rmax = Math.max(Integer.parseInt(arr[j]),rmax);
                    rmin = Math.min(Integer.parseInt(arr[j]),rmin);
                }else {
                    bmax = Math.max(Integer.parseInt(arr[j]),bmax);
                    bmin = Math.min(Integer.parseInt(arr[j]),bmin);
                }
            }

            int max = Math.max(rmax - rmin, bmax - bmin);
            max = Math.max(max,rmax-bmin);
            bw.write(Long.toString(max));
            bw.newLine();
        }
        bw.flush();
    }
}
// vx公众号关注TechGuide 实时题库 闪电速递

代码

Python版本
for _ in range(int(input())):
    n = int(input())
    *a, = map(int, input().split())
    c=input()
    red = [a[i] for i in range(n) if c[i] == 'R']
    blue = [a[i] for i in range(n) if c[i] == 'B']
    if not red:
        print(max(blue) - min(blue))
        continue
    if not blue:
        print(max(red) - min(red))
        continue
    rmax, rmin = max(red), min(red)
    bmax, bmin = max(blue), min(blue)

    if rmax >= bmax:
        if bmin <= rmin:
            print(abs(rmax - bmin))
        else:
            print(abs(rmax - rmin))
    else:
        # 动红
        ans = abs(bmax - min(bmin, rmin + bmax - rmax))

        # 动蓝
        ans = min(ans, rmax - min(bmin - bmax + rmax,rmin))
        print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>

using namespace std;

int main() {
  int t;
  cin >> t;
  for (int i = 0; i < t; i++) {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int j = 0; j < n; j++)
      cin >> a[j];
    string s;
    cin >> s;

    int maxr = 0, maxb = 0, minr = 1e9 + 1, minb = 1e9 + 1;
    for (int j = 0; j < n; j++) {
      if (s[j] == 'R') {
        maxr = max(a[j], maxr);
        minr = min(a[j], minr);
      }
      else {
        maxb = max(a[j], maxb);
        minb = min(a[j], minb);
      }
    }
    if (maxr == 0) {
      cout << maxb - minb << endl;
      continue;;
    }
    if (maxb == 0) {
      cout << maxr - minr << endl;
      continue;
    }
    if (maxr >= maxb && minr >= minb) {
      cout << maxr - minb << endl;
      continue;
    }
    int difr = maxr - minr;
    int difb = maxb - minb;
    cout << max(difr, difb) << endl;

  }

  return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递

第四题:矩阵最大权值

题目描述

游游定义一个矩阵权值为:每一对相邻元素之和的总和。

例如,对于矩阵:
12
34

它的权值是(1+2)+(1+3)+(2+4)+(3+4)=3+4+6+7=20。

游游希望你构造一个nn的矩阵,矩阵中的元素为1到nn且每个数恰好出现一次。她希望最终矩阵的权值尽可能大。你能帮帮她吗?

由于矩阵可能过大,你不需要输出最终的矩阵,只需要输出这个最大权值即可。答案对1e9+7取模。

输入描述

一个正整数 n(2 <n <1e9)

input:

2

输出描述

矩阵的最大权值,对1e9+7取模。

20

思路

1,2,3,4只用计算2次
5到 4n-4 需要计算三次
4n-4+1到 n*n 需要计算4次

用等差数列求和
设求l,r
则(r-l+1)(l+r)/2
我们假设为a
b/2
a和b都是1e9的,需要用大整数相乘

代码

Java版本
import java.util.Scanner;
public class third {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextInt();
        long u = n*n;int mod = (int)1e9+7;
        long len =( u-(n-1)*4)%mod;
        long res = (((2*u-len+1))%mod*len*2)%mod;
        long le = u - len - 4;
        long prenum = (u-len+5);
        if((le&1)==1){
            prenum = (prenum>>1)%mod;
            res = (res+(prenum*(le%mod)*3)%mod)%mod;
        }else {
            prenum = prenum%mod;
            le = (le>>1)%mod;
        }
        res = (res+20+(prenum*(le%mod)*3)%mod)%mod;
        System.out.println(res);
    }
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
n = int(input())
arr = list(range(1, n * n + 1))
mod = int(1e9) + 7

central = (n - 2) * (n - 2)
edge = (n - 2) * 4
point = 4

def get(l, r):
    return ((r + l) * (r - l + 1) // 2) % mod

ans = 2 * get(1, 4)
v = 5
ans = (ans + get(v, v + edge - 1) * 3) % mod
v += edge
ans = (ans + get(v, v + central - 1) * 4) % mod
print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
携程的Java校招笔试题主要考察对Java语言的基础知识和应用能力的掌握。下面我将用300字中文回答一道携程Java校招笔试题。 题目描述:有一个包含N个元素的整数组,数组中的元素可正可负。编写一个函数,返回数组中所包含元素的最大连续子数组的和。 解题思路:这是一道求最大连续子数组和的经典问题,可以使用动态规划的思想解决。 首先,我们定义两个变量max和currentSum,分别用于保存当前的最大连续子数组和和当前元素的和。初始时,将max和currentSum都设置为数组中的第一个元素。 然后,我们从数组的第二个元素开始遍历。对于每个元素,我们将其与之前的currentSum相加,并与该元素本身进行比较。如果大于当前元素,则更新currentSum为这个和,否则,将currentSum设置为当前元素。 同时,我们还需要将currentSum与max进行比较,如果大于max,则更新max为currentSum。这样,每次遍历的时候都会更新最大连续子数组和。 最后,当遍历完整个数组后,max中保存的就是最大连续子数组的和。将其返回即可。 代码示例: ```java public int maxSubArraySum(int[] nums) { int max = nums[0]; int currentSum = nums[0]; for (int i = 1; i < nums.length; i++) { currentSum = Math.max(currentSum + nums[i], nums[i]); max = Math.max(max, currentSum); } return max; } ``` 这个函数的时间复杂度是O(N),其中N是数组的长度。 通过以上的解题思路和示例代码,我们可以在面试中灵活应用,解决类似的最大连续子数组和的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值