美团java后端实习 在线笔试 4.16
emmm,五个编程题,就做出四题,最后题盲猜是dp,不过没时间做了。
以下是前四个题的代码:
1、第一题要考虑两个情况:一个是每个人只能算一次,还有种是并列第一的情况
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
int N = cin.nextInt();
int M = cin.nextInt();
int[][] score = new int[N][M];
int[] maxScore = new int[M];
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
score[i][j] = cin.nextInt();
maxScore[j] = score[i][j]>maxScore[j]?score[i][j]:maxScore[j];
}
}
Set<Integer> set = new HashSet<>();
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
if(score[j][i]==maxScore[i])
set.add(j);
}
}
System.out.println(set.size());
}
}
2、就是把题目给的循环实现了下,遇到一个已经出现过的x就结束循环,对循环次数进行计数,然后把类型改成了long,防止爆int,然后就能过了
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
int a,b,m,x;
a = cin.nextInt();
b = cin.nextInt();
m = cin.nextInt();
x = cin.nextInt();
boolean[] flag = new boolean[m];
int ans = 0;
while(true){
x = (int)(((long)a*(long)x+(long)b)%(long)m);
if(flag[x]==true)
break;
ans++;
flag[x]=true;
}
System.out.println(ans);
}
}
3、第三题看代码应该能看懂,我给测试样例吧,比如:
3 3
3 3 4
这个结果应该是(3,3)而不是(3,4)
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
int N = cin.nextInt();
long K = cin.nextLong();
Map<Integer,Integer> map = new HashMap<>();
for(int i=0;i<N;i++){
int tmp = cin.nextInt();
Integer temp = map.get(tmp);
if(temp == null){
map.put(tmp,1);
}else{
map.put(tmp,temp+1);
}
}
int[] num = new int[map.size()];
int numLength = 0;
for(int tmp:map.keySet()){
num[numLength++] = tmp;
}
Arrays.sort(num);
System.out.print("(");
long totalCnt = 0;
for(int i=0;i<numLength;i++){
long cnt = (long)map.get(num[i]);
if(totalCnt+cnt*N>=K){
System.out.print(num[i]+",");
for(int j=0;j<numLength;j++){
long _cnt = (long)map.get(num[j]);
if(totalCnt + _cnt*cnt >= K){
System.out.print(num[j]+")");
break;
}
totalCnt+=_cnt*cnt;
}
break;
}
totalCnt+=cnt*N;
}
}
}
4、第四题首先对数组排序,然后在数组中查找是否有K,若没有,先使用一次插入操作,把K插在该插的位置,然后因为数组中可能有多个K,则记录最左K的下标minI,和最右K下标maxI,然后就进行插入操作,从插入0次开始,分别计算插在最左边和插在最右边的时候,minI~maxI是否包含伪中位数的下标。
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
int N = cin.nextInt();
long K = cin.nextLong();
int[] num = new int[N];
for(int i=0;i<N;i++){
num[i] = cin.nextInt();
}
Arrays.sort(num);
int maxI,minI;
for(maxI=N-1;maxI>=0;maxI--){
if(num[maxI]==K)
break;
}
for(minI=0;minI<N;minI++){
if(num[minI]==K)
break;
}
int ans=0;
if(maxI<0){
int i;
for(i=0;i<N;i++){
if(num[i]>K)
break;
}
maxI=i;
minI=i;
ans++;
N++;
}
for(int j=0;;j++){
if(maxI+1+j >= (N+j+1)/2 && minI+1+j <= (N+j+1)/2 || maxI+1 >= (N+j+1)/2 && minI+1 <= (N+j+1)/2){
System.out.println(ans+j);
break;
}
}
}
}



