美团(3.26) & 招行信用卡中心(3.27) Java开发岗位笔试实录

美团

1. 第一题

题目描述:

首先给出你一个整数,可能为正也可能为负,这个数字中仅包含数字1-9,
现在定义一个1-9的置换,即指定将整数中的某个数字按顺序变换为另一个数字,
请你输出变换以后的数字是多少。

输入输出:

输入第一行包含一个整数a。(-101000<=a<=101000)
输入第二行包含9个以空格隔开的整数a_i , 第i个整数表示将数字i替换为数字a_i。(1<=a_i<=9)

样例输入输出:

样例输入:
1234567
9 8 7 6 5 4 3 2 1
样例输出:
9876543

参考思路:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        boolean flag = true;// 如果是正数就是true,负数就是false

        String Num = cin.nextLine();
        if (Num.charAt(0) == '-') {
            flag = false;
            Num = Num.substring(1);
        }


        String numMap = cin.nextLine();
        String[] List = numMap.split(" ");

        String result = "";
        for (int index = 0; index < Num.length(); index++){
            int I = Num.charAt(index) - '0';
            result += List[I - 1];
        }

        if (!flag)
            result = "-" + result;
        System.out.println(result);

    }
}

2. 第二题

题目描述:

有这么一个奇怪的符号:在一张正方形的纸上,有许多不同半径的圆。他们的圆心都在正方形的重心上(正方形的重心位于正方形两条对角线的交叉点上)。
最大的圆的外面部分是白色的。最外层的圆环被涂成了黑色,接下来第二大的圆环被涂层白色,接下来第三大的圆环被涂层黑色。以此类推,例如下图。
现在,给你这些圆的半径,请问黑色部分的面积是多少?精确到小数点后5位输出(四舍五入)。

输入:

输入包含两行。第一行一个整数n,表示圆的个数。
接下来n个整数,描述每个圆的半径ri。数据保证没有两个圆的半径是一样的。(1<=n<=100 , ri<=1000)

他那个圆就类似这样:

参考思路:

  • 我拿到手第一感觉,这题是要按照圆的个数是单还是双分情况做;后来想想好像不太对。首先环形的面积是根据大圆的面积-小圆的面积,也就是:(R外-R内)*(R外+R内)*PI
  • 题目要求从最外面一个圆开始计算起往内逐步计算,也就是两两计算。但是题目还有一个要求:最小的一个圆就自动变成一个圈,不需要计算圆环的面积。我在考虑,可不可以也把它看成是大圆的面积-小圆的面积,可以!可以看作小圆的面积为0,这样计算起来就非常方便了。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class test2 {
    static Double PIE = Math.PI;

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int num1 = cin.nextInt();
        cin.nextLine();
        String nums = cin.nextLine();
        ArrayList<Integer> NumArray = new ArrayList<>();
        String[] numlist = nums.split(" ");
        for (int i = 0; i < numlist.length; i ++){
            NumArray.add(Integer.parseInt(numlist[i]));
        }
        Collections.sort(NumArray);

        NumArray.add(0,0);

        double result = 0.0;
        for (int i = num1; i > 0; i-= 2){
            int Rx = NumArray.get(i);
            int Ry = NumArray.get(i - 1);
            result += PIE*(Rx - Ry)*(Rx + Ry);
        }

        System.out.println(String.format("%.5f",result));
    }

}

3. 第三题

题目描述:

一个序列是有趣的需要满足:当且仅当这个序列的每一个元素ai 满足 i 整除ai 。
现在给定一个长度为n的数组,问这个数组有多少个非空的子序列是有趣的,由于答案可能比较大,只需要输出在模998244353意义下答案的就行了。
一个长度为n的数组的非空子序列定义为从这个数组中移除至多n-1个元素后剩下的元素有序按照原顺序形成的数组。比如说对于数组[3,2,1],
它的非空子序列有[3],[2],[1],[3,2],[3,1],[2,1],[3,2,1]。

输入输出:

输入:
第一行一个整数n表示序列的长度。(1<=n<=1e5)
第二行n个整数表示给定的序列。(1<=ai<=1e6)
输出:
输出一个数表示有趣的子序列的个数。

样例输入输出:

样例输入:
2
3 1
样例输出:
2

参考思路:

  • 这题关键在于如何得出所有的子序列。我是用递归解的,感觉有点丑……
  • 如果A是B的子序列,C是B的子序列,那么C一定是A的子序列。
import java.util.ArrayList;
import java.util.Scanner;

public class test3 {
    static boolean Judge(ArrayList<Integer> list){
        for (int i = 0; i < list.size(); i ++){
            if (list.get(i)%(i+1) != 0)
                return false;
        }
        return true;
    }

    static ArrayList<ArrayList<Integer>> subListCollection = new ArrayList<>();
    static int result = 0;

    static void getSubString(ArrayList<Integer> array) {
        if (array.size() == 1)
            return;
        else {
            for (int i = 0; i < array.size(); i++) {
                ArrayList<Integer> temp =(ArrayList<Integer>)array.clone();
                temp.remove(i);
                if (!subListCollection.contains(temp))
                    subListCollection.add(temp);
                if (Judge(temp))
                    result++;
                getSubString(temp);
            }
        }
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int N = cin.nextInt();
        cin.nextLine();
        String[] Nums2 = cin.nextLine().split(" ");
        ArrayList<Integer> NumList = new ArrayList<>();
        for (int i = 0; i < Nums2.length; i ++){
            NumList.add(Integer.valueOf(Nums2[i]));
        }

        getSubString(NumList);
        int result1 = 0;
        for (ArrayList<Integer> a : subListCollection){
            System.out.println(a);
            if (Judge(a))
                result1++;
        }
        System.out.println(result1);
        //System.out.println(result1);
    }
}

4. 第四题

题目描述:

小仓酷爱射击运动。今天的小仓会进行 N 轮射击,已知第 i 次射击,她击中靶心的概率是 a[i] -1 。
小仓想知道 N 轮射击后,偏离靶心次数为 0 ,1 ,2 次的概率分别是多少。

输入:

第一行一个数 N,代表射击轮数。
第二行 N 个数 a[i],第 i 个数为 a[i]。
1≤N≤100,000
1≤a[i]<998244353

输出:

不难证明答案可以表示成一个最简分数 p * q -1。
你需要输出三个 p * q -1 对 998244353 取模后的结果,以此来表示偏离靶心次数为 0 , 1 , 2 时的概率。
其中 q-1 是 q 在模意义下的逆元,满足 q-1* q = 1 mod 998244353。
例如 1/4, 可以写成 748683265,原因是 4 * 748683265 % 998244353 = 1,也有且仅有 x = 748683265,1 <= x < 998244353 满足乘积等于 1

样例输入:

2
2 2

样例输出

748683265 499122177 748683265

参考思路:

  • 未AC,今天想想。可以私信我探讨

5. 第五题

一个关于套娃的疯狂题目。未AC。今天想想。
在这里插入图片描述
在这里插入图片描述

招行

  • 招行的笔试搞得花里胡哨,分为选择题、编程题,甚至还有附加题。选择题一共20条,占总分的46分;编程题共2道,占总分的54道。附加题40分,并不是很硬核,甚至还有重复的;估计是为了让前面写完的同学能够尽量更好的表现自己,根据自身的特长来解答不同领域的附加题。
  • 题目在写的时候没法复制,所以招行的笔试编程题题目描述只能记个大概。

1. 第一题:

题目描述:

题目大意就是,一个人他要去参加一个party,他需要出门。他家里有n种颜色的袜子,然后分别输入这n种颜色的袜子分别有多少只。然后他问你,至少需要拿多少双袜子才能保证这其中一定有两双颜色一样的袜子?

输入:

N (有N组数据)
n(袜子颜色的数量)
a1, a2, … , an(这n种颜色的袜子分别有多少只)
n(袜子颜色的数量)
a1, a2, … , an(这n种颜色的袜子分别有多少只)
n(袜子颜色的数量)
a1, a2, … , an(这n种颜色的袜子分别有多少只)

输出:

对于每组数据,输出至少需要多少只袜子;如果不可能实现,就输出-1。

参考思路:

  • 先分析传进来的数据。它比较坑的一点就是,有可能某种颜色的袜子是0只(?),所以不能单纯的根据传进来的颜色的组数计算。
  • 考虑最坏的情况,就是每种颜色的袜子都拿不到2只——0只的拿0只,其余所有的袜子都只拿了1只;那么下一只,一定会拿到符合条件的袜子。
import java.util.ArrayList;
import java.util.Scanner;
public class Test1 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        in.nextLine();//读掉换行
        for (int i = 0; i < T; i++){
            int n = in.nextInt();
            in.nextLine();
            ArrayList<Integer> sockArray = new ArrayList<>();
            for (int k = 0; k < n; k++){
                sockArray.add(in.nextInt());
            }
            in.nextLine();
            cal(n,sockArray);
        }

    }

    static public void cal(int n, ArrayList<Integer> array){
        for (int i = 0; i < n; i++){
            if (array.get(i) > 1)
                break;
            if (i == n-1) {
                System.out.println("-1");
                return;
            }
        }
        int result = 0;
        int result2 = 0;
        for (int i = 0; i < n; i++){
            if (array.get(i) == 0)
                continue;
            if (array.get(i) == 1)
                result ++;
            else
                result2++;
        }
        System.out.println(result+result2+1);
    }
}

2. 第二题:

题目描述:

有一堆木头需要处理;原本每处理一根木头都需要花费1元;但是如果伐木工发现处理的下一根木头的长度和宽度都>=当前的木头的长度和宽度,那么下一跟木头就不收钱(?迷惑行为)
给你一组数据,问你怎么排列木头的顺序,才能得到花费最少的方案?

输入:

N (数据的组数)
(长度list
宽度list)*N

输出:

对于每一组数据,输出花费最少的方案的花费。

参考思路:

  • 我是先把数据读进来之后简单做一个按照长度的排序,让他们处理起来更方便;
  • 贪婪算法,对于当前处理的木头,直接找到队列中下一根长度、宽度都比它大的木头,并且将向后遍历过程中找到的不符合条件的木头全部放到队列末尾。这样就能找到最优方案(虽然效率差了点)
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Test2 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        in.nextLine();//读掉换行
        for (int i = 0; i < T; i++){
            int n = in.nextInt();
            in.nextLine();
            ArrayList<Wood> Woods = new ArrayList<>();
            for (int k = 0; k < n; k++){
                Wood temp = new Wood();
                temp.setLength(in.nextInt());
                Woods.add(temp);
            }
            in.nextLine();
            for (int j = 0; j < n; j++){
                Woods.get((j)).setWeight(in.nextInt());
            }
            cal(Woods);
            in.nextLine();
        }
    }

    static public void cal(ArrayList<Wood> woodsArray) {
        if (woodsArray.size() == 1)
        {
            System.out.println("1");
            return;
        }
        Collections.sort(woodsArray);
        for (int j = 0; j < woodsArray.size() - 1; j++) {
            for (int i = j+1; i < woodsArray.size(); i++) {
                Wood w1 = woodsArray.get(j);
                Wood w2 = woodsArray.get(i);
                if (w2.getWeight() >= w1.getWeight()) {
                    woodsArray.add(j + 1, w2);
                    woodsArray.remove(i+1);
                    break;
                }
            }
        }
        int result = 1;
        for (int i = 1; i < woodsArray.size(); i ++){
            Wood w1 = woodsArray.get(i-1);
            Wood w2 = woodsArray.get(i);
            if (w2.getLength()>=w1.getLength() && w2.getWeight()>=w1.getWeight())
                continue;
            else
                result++;
        }
        System.out.println(result);
    }
}

class Wood implements Comparable {
    private int length;
    private int weight;

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    @Override
    public int compareTo(Object o) {
        Wood B = (Wood) o;
        if (this.getLength() > B.getLength())
            return 1;
        if (this.getLength() < B.getLength())
            return -1;
        else
        {
            if (this.getWeight() > B.getWeight())
                return 1;
            else return -1;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章