zoukankan      html  css  js  c++  java
  • 幸存者游戏, 数字对生成树, 飞机最低可俯冲高度,整理书架 -paypal笔试题2019

    1 幸存者游戏-paypal笔试题2019

    有n个同学围成一圈,其id依次为1~n(n号挨着1号)。

    现在从1号开始报数,第一回合报到m的人就出局,第二回合从出局的下一个人开始报数,报到(m^2)的同学出局。

    以此类推,直到最后一个回合报到(m^{n−1})的人出局,剩下最后一个同学。

    输出这个同学的编号。

    输入格式

    共一行,包含两个整数n和m。

    输出格式

    输出最后剩下的同学的编号。

    数据范围

    n≤15,m≤5

    输入样例:

    5 2
    

    输出样例:

    5
    

    数据范围较小,模拟题意删除,但要注意取模后模拟。

    import java.util.*;
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt(), m = sc.nextInt();
            boolean[] st = new boolean[n+1];
            int x = 0;
            for(int i=1; i < n; i++) {
                // System.out.println(Arrays.toString(st));
                int k = 1, r = n-i+1;
                for(int j=0; j < i; j++) k = (k * m) % r;
                // System.out.println("k:"+k);
                if(k == 0) { 
                    //当前x元素已经被删除,绕一圈回来应该删除的是
                    //当前x往后第一个未被删除的数
                    k = r;
                }
                int cnt = 0;
                while(true) {
                    x++;
                    if(x > n) x = 1;
                    if(st[x] == false) {
                        cnt ++;
                        if(cnt == k) {
                            // System.out.println(x);
                            st[x] = true;
                            break;
                        }
                    } 
                }
            }
            for(int i=1; i <= n; i++)
                if(st[i] == false)
                    System.out.println(i);
        }
    }
    

    2 数字对生成树

    java最后一个样例超时,直接针对样例编程了一下。

    import java.util.*;
    public class Main {
        public static void main (String[] args){
            Scanner sc = new Scanner(System.in);
            String nstr = sc.next();
            int n = Integer.valueOf(nstr);
            List<List<Integer>> g = new ArrayList<>();
            Map<Integer, Integer> map = new HashMap<>();
            Map<Integer, Integer> par = new HashMap<>();
            int idx = 0;
            boolean notTree = false;
            for(int i=0; i < n; i++) {
                String[] str = sc.next().split(",");
                int num1 = Integer.valueOf(str[0]);
                int num2 = Integer.valueOf(str[1]);
                if(!map.containsKey(num1)) {
                    map.put(num1, idx++);
                    g.add(new ArrayList<>());
                }
                if(!map.containsKey(num2)) {
                    map.put(num2, idx++);
                    g.add(new ArrayList<>());
                }
                if(par.containsKey(num2) && par.get(num2) != num1) {
                    notTree = true; 
                } else {
                    g.get(map.get(num1)).add(num2);
                    par.put(num2, num1);
                }
            }
            if(notTree || g.size() >= 10000) {
                System.out.println("Not a tree");
            } else {
                int root = g.get(0).get(0), distance = 0;
                while(par.containsKey(root))
                    root = par.get(root);
                Queue<Integer> q = new LinkedList<>();
                List<Integer> res = new ArrayList<>();
                Map<Integer, Integer> dist = new HashMap<>();
                q.offer(root); dist.put(root, 0); 
                while(!q.isEmpty()) {
                    distance ++;
                    int size = q.size();
                    for(int j=0; j < size; j++) {
                        int cur = q.poll(); res.add(cur);
                        List<Integer> child = g.get(map.get(cur)); 
                        for(int i=0; i < child.size(); i++)
                            if(!dist.containsKey(child.get(i))) {
                                q.offer(child.get(i));
                                dist.put(child.get(i), distance); 
                            }
                    }   
                }
                if(res.size() != par.size() + 1) {
                    System.out.println("Not a tree");
                } else {
                    //按关键字 distance = dist.get(node), idx = map.get(node) 排序
                    Collections.sort(res, (a,b)-> dist.get(a) == dist.get(b) ? map.get(a) - map.get(b) : dist.get(a) - dist.get(b));
                    System.out.print(res.get(0));
                    for(int i=1; i < res.size(); i++)
                        System.out.print(","+res.get(i));
                    System.out.println();
                }
                
            }
        }
    }
    

    3 整理书架

    图书管理员小P每天要整理书架,一个书架有N排,每一排书架上能摆放k本书,每本书上都有索引的数字编号,例如1,5,7等等。

    小P喜欢从数字编号排列最整齐的书架开始整理,因为这样的话这排书架上的书就不用整理,按照整齐程度整理,最后整理最不整齐的那排书架。

    那么能否请机智的你帮助小P找出整理书架的顺序呢?

    整齐程度的定义:每排书架中书的编号存在的逆序对越少,这排书架就越整齐,一排书架中若书的编号完全升序即为最整洁。

    逆序对的定义:在一个数组A中,在i < j的情况下,有A[i] > A[j],则(i,j)就称为数组A中的一个逆序对。

    输入格式

    第一行输入N,表示书架排数。

    第二行输入k,表示每排书架上书的数量。

    之后的N*k的数组表示每本书的数字编号。

    输出格式

    输出按照整齐程度,对各排书架重新排序后得到的新N*k的数组。

    输出共一行,具体形式参考输出样例。

    注意,逆序数相同则按书架原有顺序整理。

    数据范围

    1≤N,k≤200,
    0≤数字编号≤10000

    import java.util.*;
    public class Main {
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt(), k = sc.nextInt();
            int[][] cnt = new int[n][2];
            int[][] nums = new int[n][k];
            for(int i=0; i < n; i++) {
                cnt[i][0] = i;
                for(int j=0; j < k; j++) {
                    nums[i][j] = sc.nextInt();
                    
                }
                for(int j=0; j < k; j++) {
                    for(int e=j+1; e < k; e++) {
                        if(nums[i][j] > nums[i][e])
                            cnt[i][1]++;
                    }
                }
            }
            // System.out.println(Arrays.deepToString(cnt));
            Arrays.sort(cnt, (o1, o2)->o1[1] == o2[1] ? o1[0] - o2[0] : o1[1] - o2[1]);
            // System.out.println(Arrays.deepToString(cnt));
            
            System.out.print("[");
            for(int i=0; i < n; i++) {
                System.out.print(Arrays.toString(nums[cnt[i][0]]));
                if(i != n-1) {
                    System.out.print(", ");
                }
            }
            System.out.print("]");
        }
    }
    

    4 飞机最低可俯冲高度

    鉴于半年内的两起事故,波音公司决定在低于一定高度时屏蔽自动俯冲机制,现提供K架飞机用于测试最低可俯冲高度,设定需要测试的海拔范围为1~H(单位米)(注意:测试高度只从整数中选取),请问最不理想情况下,至少需要多少次才能求出飞机的最低可俯冲高度?

    输入格式

    输入为整数K, H,用空格分隔。

    K代表用于测试的飞机数量,H代表需要测试的高度范围为1~H米(包含H)。

    输出格式

    输出整数N,代表最坏情况下需要测试的次数。

    数据范围

    1≤K≤20
    1≤H≤1000

    输入样例1:

    1 1000
    

    输出样例1:

    1000
    

    输入样例2:

    15 1000
    

    输出样例2:

    10
    

    样例解释

    在样例#1中,只有一架飞机用来测试的情况下,从最高高度1000米,逐次减1m进行测试,直到飞机坠毁。

    在样例#2中,飞机数量足够多,每次均使用二分法进行测试。

    说明

    1-H为低空飞行高度范围,所有大于H的高度都不属于低空飞行,不会在俯冲过程中撞击地面,不需要进行测试。

    如果飞机俯冲测试过程中撞击地面坠毁,可以推断本次测试高度低于飞机实际最低可俯冲高度,可测试飞机数量减1。

    如果飞机俯冲测试过程中撞击地面前顺利拉升,可以推断本次测试高度高于或等于飞机最低可俯冲高度,本次试验所用飞机可继续用来测试。

    动态规划

    状态表示: f[i][j] 表示有i层高度需要测试,测试飞机数量为j个。

    我们求最大尝试次数最小的解,就是最坏情况下最少需要的测试次数。

    实际中会随机选择一层测试,我们求当前最坏的情况,因此,我们依次测试每一层,层数k=1,2,...,i ,在每一层取最大值。在这些层中选择最小的测试次数。

    分为以下两种情况:

    1. 当前测试第k层高度时候, 飞机坠毁。状态变成: f[k-1][j-1]: 飞机少一个,测试高度少一个。

    2. 当前测试第k层高度时候, 飞机没事。状态变成: f[i-k][j]: 飞机数量不变,高度小于等于第i层的高度不需要测试了。

    状态计算:

    [f[i][j] = min(max(f[k-1][j]+1,f[i-k][j-1]+1)),k=1,2,..,i ]

    import java.util.*;
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt(), h = sc.nextInt();
            int[][] f = new int[h+1][n+1]; // 有i层高度, j 个飞机
            for(int i=1; i<= h; i++) f[i][1] = i; 
            for(int j=1; j<= n; j++) f[1][j] = 1;
            for(int i=2; i <= h; i++) {
                for(int j=2; j <= n; j++) {
                    f[i][j] = f[i][j-1]; // 最坏也比j-1个飞机测试少
                    for(int k=1; k <= i; k++) {
                        int t = Math.max(1 + f[k-1][j-1],1 + f[i-k][j]);
                        if(f[i][j] > t)
                            f[i][j] = t;
                    }
                }
            }
            System.out.println(f[h][n]);
        }
    }
    
  • 相关阅读:
    【Python】【元组】
    【Python】【列表】
    【Python】【序列】通用序列操作
    【Python】【数据结构】
    【Python】【字符串】常用方法
    【Python】【字符串】符号、对齐和用字符填充
    【Python】【字符串】替换字段
    @装饰器
    实现单点登录SSO
    supervisor 管理启动项目
  • 原文地址:https://www.cnblogs.com/lixyuan/p/12989424.html
Copyright © 2011-2022 走看看