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<H.length; 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<N; i++) {
H[i] = sc.nextInt();
}
int count = 0;
int start = 0;
while(start<N) {
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<N; i++) {
if(H[i]<groupMax) {
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<RelationShip> relationShips = new ArrayList<RelationShip>();
HashMap<Integer, Integer> Sizes = new HashMap<Integer, Integer>(); //Id对应的关系数量
ArrayList<Integer> results = new ArrayList<Integer>(); //存放结果
for(int i=0; i<m; 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<removeGirlId) {
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<size; 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+" ");
}
}
}