笔试强训day21

一、选择题

1、设一个有序的单链表中有n个结点,现要求插入一个新结点后使得单链表仍然保持有序,则该操作的时间复杂度()
A O(log2n)
B O(1)
C O(n2)
D O(n)
他的回答: B (错误)
正确答案: D
2、一个栈的初始状态为空。首先将元素5,4,3,2,1 依次入栈,然后退栈一次,再将元素A,B,C,D依次入栈,之后将所有元素全部退栈,则所有元素退栈(包括中间退栈的元素)的顺序为?
A 1DCAB2345
B 1DCBA2345
C 54321ABCD
D DCBA12345
他的回答: B (正确)
正确答案: B
3、设栈S和队列Q的初始状态为空,元素e1,e2,e3,e4,e5,e6依次压入栈S,一个元素出栈后即进入队列Q,若出队列的顺序为e2,e4,e3,e6,e5,e1则栈S的容量要求最小值为
A 2
B 3
C 4
D 5
他的回答: A (错误)
正确答案: B
4、给定下列程序,那么执行printf(“%d\n”, foo(20, 13));的输出结果是________。

int foo(int x, int y){
if (x <= 0 || y <= 0)
return 1;
return 3 * foo( x-6, y/2 );
}

A 3
B 9
C 27
D 81
他的回答: A (错误)
正确答案: D
参考答案:
解析:foo(20, 13) = 3 * foo(14, 6) = 3 * 3 * foo(8, 3) = 3 * 3 * 3 * foo(2, 1) = 3 * 3 * 3 * 3 * foo(-4, 0) =3 * 3 * 3 * 3 * 1 = 81
答案:D
5、在具有 2n 个结点的完全二叉树中,叶子结点个数为( )
A n
B n+1
C n-1
D n/2
他的回答: C (错误)
正确答案: A
参考答案:
完全二叉树是指除最后一层外,每一层上的结点数均达到最大值,在最后一层上只缺少右边的若干结点。根据完全二叉树性质,如果共 2n 个结点,从根结点开始按层序用自然数 1 , 2 ,…, 2n 给结点编号,则编号为 n 的结点左子结点编号为 2n ,因此叶子结点编号为 n+1,n+2, … ,2n 。故叶子结点个数为 n ,本题
答案为 A 选项。
6、下列叙述中错误的是( )
A 二叉链表是二叉树的存储结构
B 循环链表是循环队列的存储结构
C 栈是线性结构
D 循环队列是队列的存储结构
他的回答: B (正确)
正确答案: B
参考答案:
循环队列是队列的一种顺序存储结构,用队尾指针 rear 指向队列中的队尾元素,用排头指针 front 指向排头元素的前一个位置。循环链表是用不连续的存储单元存储数据,它有一个表头结点,队头指针指向表头结点,最后一个结点的指针域指向表头结点。二叉链表是树的二叉链表实现方式。栈是一种特殊存取方式的线性表。故本题答案为 B 选项。
7、下述二叉树中,哪一种满足性质:从任一结点出发到根的路径上所经过的结点序列按其关键字有序()
A 二叉排序树
B 哈夫曼树
C AVL树
D 堆
他的回答: A (错误)
正确答案: D
8、为提高散列(Hash)表的查找效率,可以采取的正确措施是( )。
Ⅰ.增大装填(载)因子
Ⅱ.设计冲突(碰撞)少的散列函数
Ⅲ.处理冲突(碰撞)时避免产生聚集(堆积)现象
A 仅Ⅰ
B 仅Ⅱ
C 仅Ⅰ、 Ⅱ
D 仅Ⅱ、 Ⅲ
他的回答: A (错误)
正确答案: D
9、将整数数组(7-6-3-5-4-1-2)按照堆排序的方式原地进行升序排列,请问在第一轮排序结束之后,数组的顺序是_____。
A 2-6-3-5-4-1-7
B 6-2-3-5-4-1-7
C 6-5-3-2-4-1-7
D 1-5-3-2-4-6-7
E 5-4-3-2-1-6-7
F 5-1-3-2-4-6-7
他的回答: B (错误)
正确答案: C
10、下列各排序法中,最坏情况下的时间复杂度最低的是( )
A 希尔排序
B 快速排序
C 堆排序
D 冒泡排序
他的回答: C (正确)
正确答案: C
参考答案:
堆排序最坏情况时间下的时间复杂度为 O(nlog2n) ;希尔排序最坏情况时间下的时间复杂度为 O(n1.5) ;快速排序、冒泡排序最坏情况时间下的时间复杂度为O(n2) 。故本题答案为 C 选项。

二、判断题

**【洗牌】**洗牌在生活中十分常见,现在需要写一个程序模拟洗牌的过程。 现在需要洗2n张牌,从上到下依次是第1张,第2张,第3张一直到第2n张。首先,我们把这2n张牌分成两堆,左手拿着第1张到第n张(上半堆),右手拿着第n+1张到第2n张(下半堆)。接着就开始洗牌的过程,先放下右手的最后一张牌,再放下左手的最后一张牌,接着放下右手的倒数第二张牌,再放下左手的倒数第二张牌,直到最后放下左手的第一张牌。接着把牌合并起来就可以了。 例如有6张牌,最开始牌的序列是1,2,3,4,5,6。首先分成两组,左手拿1,2,3;右手拿着4,5,6。在洗牌过程中按顺序放下了6,3,5,2,4,1。把这六张牌再次合成一组牌之后,我们按照从上往下的顺序看这组牌,就变成了序列1,4,2,5,3,6。 现在给出一个原始牌组,请输出这副牌洗牌k次之后从上往下的序列。
输入描述:
第一行一个数T(T ≤ 100),表示数据组数。对于每组数据,第一行两个数n,k(1 ≤ n,k ≤ 100),接下来一行有2n个数a1,a2,…,a2n(1 ≤ ai ≤ 1000000000)。表示原
始牌组从上到下的序列。

输出描述:
对于每组数据,输出一行,最终的序列。数字之间用空格隔开,不要在行末输出多余的空格。
示例1:
输入
3 3 1 1 2 3 4 5 6 3 2 1 2 3 4 5 6 2 2 1 1 1 1
输出
1 4 2 5 3 6 1 5 4 3 2 6 1 1 1 1

【解题思路】:
每次读取一个数之后,算出他经过k次洗牌后的位置,只用一个长度为2n数组用来输出
根据当前数的位置,可以算出经过一次洗牌后的位置
如果当前数小于等于n(即在左手),则他下次出现的位置是 2当前位置
与之对应的当前位置 + n(即在右手)的牌,则他下次出现的位置是 2
当前位置 + 1

import java.util.*;
public class Main{
    public static void playCard(int[] cards, int n, int k){
        // i --> 2 * i
         // i + n ---> 2 * i + 1
        for(int i = 0; i < k; ++i){
             //一次洗牌的过程
            int[] newCards = new int[cards.length];
            //遍历编号为 0 ~ n - 1
                for(int j = 0; j < n; ++j){
                        newCards[2 * j] = cards[j];
                        newCards[2 * j + 1] = cards[j + n];
                }
            cards = newCards;
        }
        //从上往下打印
        printCard(cards);
    }
    public static void printCard(int[] cards){
        for(int i = 0; i < cards.length - 1; ++i){
            System.out.print(cards[i] + " ");
        }
        System.out.println(cards[cards.length - 1]);
    }
    public static void main(String[] args){
        Scanner s = new Scanner(System.in);
        int groups = s.nextInt();
        for(int i = 0;i < groups; ++i){
            //读入每组数据
            int n = s.nextInt();
            int k = s.nextInt();
            int[] cards = new int[2 * n];
            for(int j = 0; j < 2 * n; ++j){
                cards[j] = s.nextInt();
            }
            //洗牌
            playCard(cards, n, k);
        }
    }
}

【MP3光标位置】
MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。
现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:
歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。
光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。
在这里插入图片描述
其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。
在这里插入图片描述

  1. 歌曲总数大于4的时候(以一共有10首歌为例):
    特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
    在这里插入图片描述
    一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。
    在这里插入图片描述
    其他情况,不用翻页,只是挪动光标就行。
    数据范围:命令长度1<=s<=100 ,歌曲数量1<=n<=50
    进阶:时间复杂度:O(n) ,空间复杂度:O(n)
    输入描述:
    输入说明:
    1 输入歌曲数量
    2 输入命令 U或者D

输出描述:
输出说明
1 输出当前列表
2 输出当前选中歌曲

示例1:
输入
10
UUUU
输出
7 8 9 10
7

【解题思路】:
本题比较简单,通过解析指令,进行移动即可,分两种情况,歌曲数目不大于4和大于4的情况。

import java.util.*;
import java.io.*;
public class Main{
    public static void mouseMove(String numStr, String orderStr){
        //歌曲数量
        int n = Integer.parseInt(numStr);
        //指令数组: UD
        char[] order = orderStr.toCharArray();
        //当前鼠标所在的位置
        int mouse = 1;
        //显示列表所在的起始位置
        int first = 1;
        //指令处理
        //n <=4
        if(n <= 4){
            //循环处理每一个指令
            for(int i = 0; i < order.length; ++i){
                //光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲
                if(mouse == 1 && order[i] == 'U')
                    mouse = n;
                //光标在最后一首歌曲时,按Down键光标挪到第一首歌曲
                else if(mouse == n && order[i] == 'D')
                        mouse = 1;
                //其他情况下用户按Up键,光标挪到上一首歌曲
                else if(order[i] == 'U')
                        --mouse;
                //用户按Down键,光标挪到下一首歌曲
                else if(order[i] == 'D')
                        ++mouse;
                }
                //输出
                //打印当前的显示列表
                for(int i = 1; i < n; ++i)
                    System.out.print(i + " ");
                    System.out.println(n);
                    //打印当前歌曲
                    System.out.println(mouse);
                }else{
                     //n > 4
                    for(int i = 0; i < order.length; ++i){
                    //屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,
                    //用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),
                    //同时光标放到最后一首歌上。
                        if(first == 1 && mouse == 1 && order[i] == 'U'){
                            //最右一页的起始位置
                            first = n - 3;
                            mouse = n;
                        }
                        //同样的,屏幕显示最后一页时,光标在最后一首歌曲上,
                        //用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
                        else if(first == n - 3 && mouse == n && order[i] == 'D'){
                                first = 1;
                                mouse = 1;
                        }
                        //屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,
                        //屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。
                        else if(first != 1 && mouse == first && order[i] == 'U'){
                                    --mouse;
                                    --first;
                        }
                        //屏幕显示的不是第一页时,光标在当前屏幕的最后一首歌时的
                        //按Down键,屏幕从当前歌曲的下一首开始显示,光标也挪到下一首歌曲
                        else if(first != n - 3 && mouse == first + 3 && order[i] == 'D'){
                                    first++;
                                    mouse++;
                        }
                        //其它情况,只移动光标
                        else if(order[i] == 'U')
                                --mouse;
                        else if(order[i] == 'D')
                                ++mouse;
                        }
                        //输出
                        //打印当前的显示列表
                        for(int i = first; i < first + 3; ++i)
                                System.out.print(i + " ");
                                System.out.println(first + 3);
                                //打印当前歌曲
                                System.out.println(mouse);
            }
     }
    public static void main(String[] args) throws Exception{
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String numStr;
            while((numStr = reader.readLine()) != null){
                String orderStr = reader.readLine();
                mouseMove(numStr, orderStr);
            }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值