> 文章列表 > 【Java版oj】day24洗牌、MP3光标位置

【Java版oj】day24洗牌、MP3光标位置

【Java版oj】day24洗牌、MP3光标位置

目录

 一、洗牌

(1)原题再现

(2)问题分析

(3)完整代码

 二、MP3光标位置

(1)原题再现

(2)问题分析

(3)完整代码


 一、洗牌

(1)原题再现

洗牌_网易有道笔试题_牛客网

        洗牌在生活中十分常见,现在需要写一个程序模拟洗牌的过程。 现在需要洗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

(2)问题分析

        本题重要的是先把一次洗牌的结果找出,根据要求k为几,就用for循环几次。

        一次洗牌的步骤:首先把所有牌分成两部分,用两个数组保存。第一幅牌数组下标是从0到所有牌的一半(len/2),第二副牌数组下标是从len/2到len。然后定义一个结果数组,用来存放洗完牌后的结果,根据题目要求,其实就是把第一副牌放在第一个位置,第二副牌放到第二个位置,一次交叉。因为结果数组下标是从0开始的,所以下标能整除2的地方就用来存放第一副牌,不能整除的存放第二副牌。注意:i等于1的时候表示,第二副牌中的第一张牌(位置下标为0)存放在结果数组的第二个位置(位置下标是1)。

(3)完整代码

import java.util.Scanner;/** 洗牌*/
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int times = sc.nextInt();while (times-- > 0) {int n = sc.nextInt();int k = sc.nextInt();int []cards = new int [2 * n];for (int i = 0; i < 2 * n; i++) {cards[i] = sc.nextInt();}for (int i = 0; i < k; i++) {cards = shuffleOneCard(cards);}for (int i = 0; i < 2 * n; i++) {if (i == 2 * n - 1) {System.out.println(cards[i]);break;}System.out.print(cards[i] + " ");}}}public static int[]shuffleOneCard(int[]cards) {int len = cards.length;int []oneCards = new int [len / 2];int []twoCards = new int [len / 2];int []res = new int [len];for (int i = 0; i < len / 2; i++) {oneCards[i] = cards[i];}for (int i = 0; i < len / 2; i++) {twoCards[i] = cards[i + len / 2];}for (int i = 0; i < len; i++) {if (i % 2 == 0) {res[i] = oneCards[i / 2];} else {res[i] = twoCards[(i - 1) / 2];}}return res;}
}

 二、MP3光标位置

(1)原题再现

MP3光标位置__牛客网
来源:牛客网
 

        MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。

        现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:

  1. 歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。

光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。

其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。

2. 歌曲总数大于4的时候(以一共有10首歌为例):

特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。

一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。

其他情况,不用翻页,只是挪动光标就行。

输入描述:

输入说明:
1 输入歌曲数量
2 输入命令 U或者D

 

输出描述:

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

示例1

输入

10

UUUU

输出

7 8 9 10

7

(2)问题分析

        这道题看似很长很复杂,其实只要根据题目要求,分情况把所有可能的结果列举出来就行了。

分情况:

1.歌曲总数1小于等于4

2.歌曲总数大于4------>特殊翻页-------->从一页往上翻页跳到最后一页

                            |                         |----->从一页往上翻页跳到最后一页

                            |---->普通翻页-------->往上翻页

                                                     |----->往下翻页

                                                     |----->不用翻页

        因为需要输出每页上的所有歌曲,所以需要start变量记录每页第一个歌曲的位置,index表示光标的位置。

(3)完整代码

import java.util.*;
/** MP3光标位置*/
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int num = sc.nextInt();String str = sc.next();if (num <= 4) {lowerFour(num, str);} else {upFour(num, str);}}//翻页public static void upFour(int num, String str) {//特殊页面int index = 1; //光标int start = 1; //每页开始第一个for (int i = 0; i < str.length(); i++) {if (start == 1 && index == 1 && str.charAt(i) == 'U') {index = num;start = num - 3;continue;}if (start == num - 3 && index == num && str.charAt(i) == 'D') {index = 1;start = 1;continue;}//普通翻页//往上翻页if (start == index && str.charAt(i) == 'U') {start--;index--;continue;}//往下翻页if (start + 3 == index && str.charAt(i) == 'D') {start++;index++;continue;}//不用翻页if (str.charAt(i) == 'U') {index--;}if (str.charAt(i) == 'D') {index++;}}System.out.print(start + " " + (start + 1) + " " + (start + 2) + " " +(start + 3));System.out.println();System.out.println(index);}//<4public static void lowerFour(int num, String str) {int index = 1; //光标for (int i = 0; i < str.length(); i++) {if (str.charAt(i) == 'U') {if (index == 1) {index = num;continue;} else {index--;continue;}}if (str.charAt(i) == 'D') {if (index == num) {index = 1;continue;} else {index++;continue;}}}for (int i = 1; i <= num; i++) {if (i == num) {System.out.println(i);break;}System.out.print(i + " ");}System.out.println(index);}}