企业面试题-招银编程题
(1)洗牌题目
题目简述
一个牌的数值分别是0,1,2,3,4,5,6,7,8,9;当用户指定一个n,即代表有n张牌,且分别是介于0~9之前的任意数组成。小明把拿到的这n张牌分为两堆,左边一堆,右边一堆,如果n是奇数张牌,就把左堆的牌数比右边多一个;如果牌数是偶数,就左右堆平均分配即可。在洗牌的时候,如果是第奇数此洗牌,就先左边一张牌(默认把牌排成一排从后边取),再拿右边一张牌,依次这样往复的出完牌。如果是偶数次洗牌,则是先从右边堆中取出一张牌,再从左边取出一张牌,依次类推取完牌。最终输出洗完牌的顺序。
举例
如:牌为1 2 3 4 5 6 (此时牌为偶数张)
偶数次洗牌得出的最终牌为:1 4 2 5 3 6
此时再把上述洗后的牌再洗牌(此时就是奇数次洗牌了):5 1 3 4 6 2
输入
第一个数为这个牌有几张(n)牌数,第二个数为洗牌的次数,后边的n个数就是牌的面值,如下
6 1 1 2 3 4 5 6 [解释:7代表7张牌,1 代表第1次洗牌,1 2 3 4 5 6 代表牌面数]
输出
4 1 5 2 6 3
java代码
package ncompanydemos.p1_zhaopin;
import java.util.Arrays;
import java.util.Scanner;
/**
* @author jiyongjia
* @create 2020/6/22 - 21:59
* @descp:
* > 题目描述:
* 一个牌的数值分别是0,1,2,3,4,5,6,7,8,9;当用户指定一个n,即代表有n张牌,且分别是介于0~9之前的任意数组成。
* 小明把拿到的这n张牌分为两堆,左边一堆,右边一堆,如果n是奇数张牌,就把左堆的牌数比右边多一个;如果牌数是偶数,
* 就左右堆平均分配即可。在洗牌的时候,如果是第奇数此洗牌,就先左边一张牌(默认把牌排成一排从后边取),再拿右边一张牌,
* 依次这样往复的出完牌。如果是偶数次洗牌,则是先从右边堆中取出一张牌,再从左边取出一张牌,依次类推取完牌。最终输出洗完牌的顺序。
* > 举例
* 如:牌为1 2 3 4 5 6 (此时牌为偶数张)
* 偶数次洗牌得出的最终牌为:1 4 2 5 3 6
* 此时再把上述洗后的牌再洗牌(此时就是奇数次洗牌了):5 1 3 4 6 2
* > 输入
* 第一个数为这个牌有几张(n)牌数,第二个数为洗牌的次数,后边的n个数就是牌的面值,如下
* 6 1 1 2 3 4 5 6 [解释:7代表7张牌,1 代表第1次洗牌,1 2 3 4 5 6 代表牌面数]
* > 输出
* 4 1 5 2 6 3
*
*/
public class Exam01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请按要求输入:");
int total = scanner.nextInt(); //总牌数
int cishu = scanner.nextInt(); //洗牌的次数
//存储牌面数
int[] arr = new int[total];
for (int i = 0; i < total; i++) {
arr[i] = scanner.nextInt();
}
//调用方法
int[] res = shuffle(total, cishu, arr);
System.out.println("输出:");
System.out.println(Arrays.toString(res));
}
//洗牌
private static int[] shuffle(int total, int cishu, int[] arr) {
int leftIndex; //指向左堆的最后一个元素
int rightIndex; //指向右堆的最后一个元素
int[] res = new int[total];
int index = arr.length - 1;//在新数组中添加元素的index
//1 如果是偶数的牌数,就分成平均的两堆
if (total % 2 == 0) {
leftIndex = arr.length / 2 - 1;
rightIndex = arr.length - 1;
int count = arr.length / 2;
while (count > 0 && (leftIndex >= 0 && rightIndex <= arr.length - 1)) {
//1.1 判断奇数次洗牌的时候,先出左牌
if (cishu % 2 == 1) {
res[index--] = arr[leftIndex--]; //先出左堆
res[index--] = arr[rightIndex--]; //再出右堆
} else { //1.2 判断偶数次洗牌的时候,先出右边堆牌
res[index--] = arr[rightIndex--]; //先出右堆
res[index--] = arr[leftIndex--]; //再出左堆
}
}
} else {//2 如果是奇数次的牌数,就分成左边比右边多一个的两堆
leftIndex = arr.length / 2;
rightIndex = arr.length - 1;
int count = arr.length / 2;
while (count > 0 && (leftIndex >= 0 && rightIndex <= arr.length - 1)) {
//2.1 判断奇数次洗牌的时候,先出左牌
if (cishu % 2 == 1) {
res[index--] = arr[leftIndex--]; //先出左堆
res[index--] = arr[rightIndex--]; //再出右堆
//左边多的那张牌出出来
res[index--] = arr[leftIndex]; //此时不减了,再减1就越界
} else { 2.2 判断偶数次洗牌的时候,先出右边堆牌
res[index--] = arr[rightIndex--]; //先出右堆
res[index--] = arr[leftIndex--]; //再出左堆
//左边多的那张牌出出来
res[index--] = arr[leftIndex]; //此时不减了,再减1就越界
}
}
}
return res;
}
}
输出验证:
验证1:
输入:6 1 1 2 3 4 5 6 (模拟奇数次洗牌)
验证2:
输入:6 2 1 2 3 4 5 6 (模拟偶数次洗牌)