京东机试有四十个选择,两个编程,四十个选择还挺常规的,分值占比也挺高的。
两个程序题,有点点麻烦,我选择用的时间有点多,程序都没有写出来。都是只过了36%,仅记录一下题目。
题目一 合唱队形
题目描述:
合唱队的N名学生站成一排且从左到右编号为1到N,其中编号为i的学生身高为Hi。现在将这些学生分成若干组(同一组的学生编号连续),并让每组学生从左到右按身高从低到高进行排列,使得最后所有学生同样满足从左到右身高从低到高(中间位置可以等高),那么最多能将这些学生分成多少组?
输入
第一行包含一个整数N,1≤N≤105。
第二行包含N个空格隔开的整数H1到HN,1≤Hi≤109。
输出
输出能分成的最多组数。
样例输入
4
2 1 3 2
样例输出
2
输入样例2
10
69079936 236011312 77957850 653604087 443890802 277126428 755625552 768751840 993860213 882053548
输出样例2
6
此时分组为:【69079936】【236011312 77957850】【653604087 443890802 277126428】 【755625552】 【768751840】【 993860213 882053548】调整顺序后即可满足条件
题目分析
从后向前遍历,要是遇到比第一个数小的,那这个数前面的所有数都要分到一个组,要是比第一个数大,则向左移动,要是和第一个数相同,这个时候需要分来讨论,因为要是分的组最多,所以要是前面都比这个数大,那么这个数也要分入这个组中,要是前面的数还有重复的,那这个重复的就可以单独一个组,有些麻烦,当时写不出来了,后来也没有再去实现。
代码实现:
import java.util.Scanner;
public class Main {
public static void main(String []args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
long hight[] = new long[N];
int num = 0;
for(int i = 0; i<N;i++){
hight[i] = in.nextLong();
}
in.close();
int i = 0;
while (i<N){
int j = N-1;
while ( j > i){
if(hight[j]> hight[i] )
j--;
else
break;
}
num++;
i = j+1;
}
System.out.println(num);
}
}
题目二 考场安排
题目描述:
某校在积极推行无人监考制度,但是总有学生是不自觉的,如果将两个很熟的异性朋友放在同一个考场里,他们就会交流甚至作弊。因此一个考场中不能允许两个很熟的异性朋友存在,学校希望通过搬出一部分学生的方法来改善这一问题。
但是又因为教室数量有限,因此希望一个教室中容下的学生尽可能多,即需要搬出教室的学生数量尽可能少,请你输出搬出教室人数最少,且字典序最小的方案。
输入
输入第一行有两个整数n和m,分别表示有n个男生和n个女生,有m个朋友关系。(1<=n<=500,1<=m<=100000)
接下来m行,每行有两个整数,x和y,表示第x号男生和第y号女生是朋友。男生的编号均为[1,n],女生的编号为[n+1,2n]。
输出
输出第一行包含一个整数a,表示最少需要搬出教室的人数。
输出第二行有a个整数,即a个需要搬出教室的人的编号,要求人数最少,且字典序最小。
样例输入
2 2
3 1
1 4
样例输出
1
1
题目分析:
使用一个二维数组保存m次关系,每次都统计出所有关系中出现的次数最多的男或者女,然后把所有包含他的关系删除,再重新统计,直到所有的关系都删干净。但是不知道为啥只过了36,望大佬指教。
代码实现:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String []args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int order [] = new int[2*n];//输出序列
int order1 [] = new int[2*n];//中间序列
Arrays.fill(order1,0);
Arrays.fill(order,0);
int num = 0;
int communication[][] = new int[m][2];//男女关系表
for (int i = 0; i < m ; i++){
int temp = in.nextInt();
int temp1 = in.nextInt();
if(temp<=n){
communication[i][0] = temp;
communication[i][1] = temp1;
}else {
communication[i][1] = temp;
communication[i][0] = temp1;
}
order1[temp-1]++;
order1[temp1-1]++;
}
while (!chack(order1)){
int findmaxpeoplelocal = findmax(order1);
order[findmaxpeoplelocal-1] = 1;
num++;
if(findmaxpeoplelocal<=n){
for(int i = 0;i < m;i++){
if(communication[i][0] == findmaxpeoplelocal)
communication[i][0] = communication[i][1] = 0;
}
}else {
for(int i = 0;i < m;i++){
if(communication[i][1] == findmaxpeoplelocal)
communication[i][0] = communication[i][1] = 0;
}
}
Arrays.fill(order1,0);
for(int i = 0;i<m;i++){
if(communication[i][0]!=0){
order1[communication[i][0]-1]++;
order1[communication[i][1]-1]++;
}
}
}
System.out.println(num);
for(int i = 0;i<2*n;i++){
if(i!=0)
System.out.print(" ");
if(order[i]!=0)
System.out.print(i+1);
}
}
public static boolean chack(int order[]){ //判断是否符合标准
int lengman = 0;
int lenggil = 0;
for(int i = 0;i<order.length;i++){
if(i>=0 &&i<order.length/2){
if(order[i]!=0)
lengman++;
}
if(i>=order.length/2 &&i<order.length){
if(order[i]!=0)
lenggil++;
}
}
if(lenggil==0 || lengman==0)
return true;
else
return false;
}
public static int findmax(int order[]){//寻找这一轮中关系网最多的人
int result = 0;
int local = 0;
for(int i = 0;i<order.length;i++){
if(order[i] > result){
result = order[i];
local = i;
}
}
order[local] = 0;
return local+1;
}
}