java某校在积极推行无人监考,JD笔试两道题复盘

1、合唱队的N名学生站成一排且从左到右编号为1到N,其中编号为i的学生身高为Hi。

现在将这些学生分成若干组(同一组的学生编号连续),并让每组学生从左到右按

身高从低到高进行排列,使得最后所有学生同样满足从左到右身高从低到高(中间位置可以等高),

那么最多能将这些学生分成多少组?

输入

第一行包含一个整数N,1≤N≤105。

第二行包含N个空格隔开的整数H1到HN,1≤Hi≤109。

输出

输出能分成的最多组数。

case 1:

样例输入

4

2 1 3 2

样例输出

2

case 2:

11

6 23 7 44 65 25 27 75 76 99 88

case 2:

6

思路如下:

1、从第一个数(下标为start)开始,将其划分成一组,这个数毫无疑问是本组最大的数groupMax。

2、从start开始往后遍历数组找到最后一个比groupMax小的数min,并记录min的下标minIndex,如果minIndex和start一样大,表明后边没有比下标为start的数小,就是说下标为start的数独自分成一组。如果minIndex比start大,这组应该扩充到下标minIndex处,该组扩充,扩充的数里面很有可能比groupMax大的数,遍历扩充的数里面是否有比groupMax大的数。如果没有比groupMax大的数,本组分组到下标为minIndex为止即可;如果有比groupMax大的数,则需要从minIndex处开始往后遍历找到最后一个比groupMax小的数。

3、每次分组完,start为本组最后一个下标加一,开始下一个分组。

4、知道start等于组大小,退出。

思路虽然比较复杂,但是还算清晰,虽然程序看起来有几重循环,其实时间复杂度真的不高。就是思路比较复杂,后来翻看牛客网网友分享的一些方法,真的是简单。大概说一下,将数组H拷贝一个数组HH,将HH排序,然后遍历H,找出H中每组最大的数max, 当遇到HH中和max相等的数字时,就在此处分组。举个例子:

H: 6 23 7 44 65 25 27 75 76 99 88

HH: 6 7 23 25 27 44 65 75 76 88 99

分组结果:

6 |7 23| 25 27 44 65| 75| 76| 88 99

package jd;

import java.util.Scanner;

public class Problem1 {

public static int getMinIndex(int[] H, int start, int groupMax) {

int minIndex = start;

int min = groupMax;

for(int i=start; i

if(H[i]<=min) {

min = H[i];

minIndex = i;

}

}

return minIndex;

}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int N = sc.nextInt();//学生数

int[] H = new int[N];//学生身高

for(int i=0; i

H[i] = sc.nextInt();

}

int count = 0;

int start = 0;

while(start

int groupMax = H[start];

int minIndex = getMinIndex(H, start, groupMax);

if(minIndex==start) {

count++;

start = minIndex+1;

} else {

int secondMinIndex = minIndex;

while(true){

for(int i=start; i<=minIndex; i++) {

if(H[i]>groupMax) {

groupMax = H[i];

}

}

for(int i=minIndex+1; i

if(H[i]

secondMinIndex = i;

}

}

if(secondMinIndex==minIndex) {

start = secondMinIndex+1;

count++;

break;

} else {

minIndex = secondMinIndex;

secondMinIndex = minIndex;

}

}

}

}

System.out.println(count);

}

}

2、某校在积极推行无人监考制度,但是总有学生是不自觉的,如果将两个很熟的异性朋友放在同一个考场里,

他们就会交流甚至作弊。因此一个考场中不能允许两个很熟的异性朋友存在,学校希望通过搬出一部分学生的方法来改善这一问题。

但是又因为教室数量有限,因此希望一个教室中容下的学生尽可能多,即需要搬出教室的学生数量尽可能少,请你输出搬出教室人数最少,且字典序最小的方案。

输入

输入第一行有两个整数n和m,分别表示有n个男生和n个女生,有m个朋友关系。

(1<=n<=500,1<=m<=100000)

接下来m行,每行有两个整数,x和y,表示第x号男生和第y号女生是朋友。男生的编号均为[1,n],女生的编号为[n+1,2n]。

输出

输出第一行包含一个整数a,表示最少需要搬出教室的人数。

输出第二行有a个整数,即a个需要搬出教室的人的编号,要求人数最少,且字典序最小。

case 1:

样例输入

2 2

3 1

1 4

样例输出

1

1

case 2:

样例输入:

4 8

1 5

1 6

2 5

2 6

3 5

3 6

4 7

4 8

样例输出:

5 6 4

本题思路比较简单:首先用用一个list维护男女生之间认识的关系,用一个map记录每个Id关联的关系数。从关系数最大的Id下手,将list中所有包含Id的关系找出来,每个关系包含的异性Idd能得到,将map中Idd的关系数量减1,最后将list中所有包括Id的关系删除。用一个list将每次移除的Id记录下来,知道list中一条关系都没有的时候,任务结束。

package jd;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Scanner;

class RelationShip {

int boyId;

int girlId;

}

public class Problem2 {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int n = sc.nextInt();//男女生数

int m = sc.nextInt();//男女生关系数

ArrayList relationShips = new ArrayList();

HashMap Sizes = new HashMap();//Id对应的关系数量

ArrayList results = new ArrayList();//存放结果

for(int i=0; i

RelationShip relationShip = new RelationShip();

int boyId = sc.nextInt();

relationShip.boyId = boyId;

Integer boySize = Sizes.get(boyId);

if(boySize==null) {

Sizes.put(boyId, 1);

} else {

Sizes.put(boyId, boySize+1);

}

int girlId = sc.nextInt();

relationShip.girlId = girlId;

Integer girlSize = Sizes.get(girlId);

if(girlSize==null) {

Sizes.put(girlId, 1);

} else {

Sizes.put(girlId, girlSize+1);

}

relationShips.add(relationShip);

}

while(relationShips.size()!=0) {

int maxSize = 0;

int removeId = 0;

int removeBoyId = 0;

int removeGirlId = 0;

int boy = 0;

int girl = 0;

for(Integer Id:Sizes.keySet()) {

int size = Sizes.get(Id);

if(1<=Id&&Id<=n) {

boy++;

} else {

girl++;

}

if(size>=maxSize) {

maxSize = size;

if(1<=Id&&Id<=n) {

removeBoyId = Id;

} else {

removeGirlId = Id;

}

}

}

if(removeBoyId>removeGirlId) {

removeId = removeBoyId;

} else if(removeBoyId

removeId = removeGirlId;

} else {//当男省最多关系数和女生最多关系数相同时,就比较那边涉及的关系少一点{

if(boy>girl) {

removeId = removeGirlId;

}else {

removeId = removeBoyId;

}

}

Sizes.remove(removeId);

results.add(removeId);

int size = relationShips.size();

int index = 0;

for(;index

RelationShip relationShip = relationShips.get(index);

if(relationShip.boyId==removeId ) {

int girlId = relationShip.girlId;

Sizes.put(girlId, Sizes.get(girlId)-1);//当boyId的关系删除之后 对应的girl关系应该减一

relationShips.remove(relationShip);

size--;

index--;

}

if( relationShip.girlId==removeId ) {

int boyId = relationShip.boyId;

Sizes.put(boyId, Sizes.get(boyId)-1);//当boyId的关系删除之后 对应的girl关系应该减一

relationShips.remove(relationShip);

size--;

index--;

}

}

}

Collections.sort(results);

System.out.print("结果是:");

for(Integer Id:results) {

System.out.print(Id+" ");

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值