蘑菇街技术笔试编程题
写在前面
1、第一题
题目描述
现有一个n个整数的序列,你要做的就是交换两个数的位置直到整个序列按照升序排列,那么将这个整数序列排好序,需要交换多少次?例如,1,2,3,5,4,我们只需要交换一次,即将5和4交换即可。
输入
输入第一行为测试数据组数T(0<T<1000)
接下来输入一个正整数n(n≤1000),表示数字序列的元素个数,占一行;
接下来一行输入从1到n的n个整数排序,中间用空格隔开
输出
序列升序排列需要的最少交换次数
样例输入
2
3
1 2 3
4
4 3 2 1
样例输出
0
6
题目分析
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
这道题明显是考察冒泡排序,记录交换次数。
代码如下:
import java.util.Scanner;
public class Main {
public static int bubbleSort(int[] nums) {
if (null == nums)
return -1;
int count = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = nums.length - 1; j > i; j--) {
if (nums[j] < nums[j - 1]) {
swap(nums, j, j - 1);
count++;
}
}
}
return count;
}
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int T = cin.nextInt();
for (int i = 1; i <= T; i++) {
int n = cin.nextInt();
int[] num = new int[n];
for(int j = 0;j<n;j++){
num[j] = cin.nextInt();
}
int res = bubbleSort(num);
System.out.println(res);
}
}
cin.close();
}
}
重点来了,我提交的结果是通过90%的测试,我感觉可能是一些边界条件没有考虑。但是思考很久,还是没找到问题所在。
欢迎各路大神给出意见。
1、第一题
题目描述
Arthur买了新桌子,桌子有很多条桌腿支撑,可是回家后发现桌子不稳,原来是桌子腿长度不太相同,他想要自己把桌子修理好,所以他决定移除掉一些桌腿来让桌子变得平稳。桌子腿共n条腿,第i条腿长度为l_i,Arthur移除第i桌腿要花费代表为d_i。假设k条腿桌子平稳的条件:超过一半桌腿能够达到桌腿长度的最大值。例如:一条腿的桌子是平稳的,两条腿的桌子腿一样长时是平稳的。请你帮Arthur计算下桌子变平稳的最小总代价。
输入
第一行是一整数:n(1 <= n <= 10^5),n表示桌腿总数
第二行数据是n个整数:l_1,l_2,...,l_n(1 <= l_i <= 10^5),表示每条桌腿的长度
第三行数据是n个整数:d_1,d_2,...,d_n(1 <= d_i <= 200),表示移除每条腿的代价
输出
让桌子变平稳的最小总代价
样例输入:
6
2 2 1 1 3 3
4 3 5 5 2 1
输出
8
题目分析
- 按桌腿长度进行排序,对应的代价数组也进行交换,保证一一对应。
- 从最高的桌腿长度len开始,如果选取最高桌腿长度为len,如果长度为len的桌腿超过一半,则代价为0,在剩余桌腿里进行移除,按代价从小到大,只要满足长度为len的桌腿超过一半,就可停止。
- 每次选择一个高度h作为最高高度,注意,当h作为最高高度时,所以比h大的桌腿已经移除,然后计算在比h低的桌腿里移除,以满足长度为h的桌腿超过一半
代码如下:
写的有点乱。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void bubbleSort(int[] a, int[] b) {
if (null == a)
return;
for (int i = 0; i < a.length; i++) {
for (int j = a.length - 1; j > i; j--) {
if (a[j] < a[j - 1]) {
swap(a, j, j - 1);
swap(b, j, j - 1);
}
}
}
}
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public static int countCost(int[] a, int[] b) {
int cost = 0;
int min = Integer.MAX_VALUE;
int maxHigh = a[a.length - 1];
int post = b[a.length - 1];
int before = 0;
int cnt = 0;
for (int i = a.length - 2; i >= 0; i--) {
while (i >= 0 && maxHigh == a[i]) {
post += b[i];
i--;
cnt++;
}
cost = cntCostpart(b, 0, i, before, cnt);
before = post;
if (min > cost)
min = cost;
cnt = 0;
if (i >= 0) {
maxHigh = a[i];
post += b[i];
cnt++;
}
}
return min;
}
public static int cntCostpart(int[] b, int start, int end, int before,
int cnt) {
int len = cnt + (end - start + 1);
int leave = end - start + 1;
if (end <= start || cnt > (int) (len / 2))
return before;
int res = 0;
int[] tmp = Arrays.copyOfRange(b, start, end + 1);
Arrays.sort(tmp);
int tmpCnt = 0;
for (int i = 0; i < tmp.length; i++) {
res += tmp[i];
tmpCnt++;
if (cnt > (leave - tmpCnt))
break;
}
return res + before;
}
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int n = cin.nextInt();
int[] numl = new int[n];
int[] numd = new int[n];
for (int i = 0; i < numl.length; i++)
numl[i] = cin.nextInt();
for (int i = 0; i < numd.length; i++)
numd[i] = cin.nextInt();
bubbleSort(numl, numd);// sort array
int cost = countCost(numl, numd);
System.out.println(cost);
}
cin.close();
}
}