贝壳笔试题解 2020-08-11
1. 给个数组,需要移除k个数使得这个数组的最大公因数为1,求k,不存在输出-1。AC
看整个序列的最大公约数是不是1,是1 返回0,不是1返回-1。
import java.util.*;
public class Main20200811001 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for(int i=0;i<T;i++){
int N = sc.nextInt();
int[] arr = new int[N];
for(int ii=0;ii<N;ii++){
arr[ii] = sc.nextInt();
}
int g = arr[0];
for(int ii=1;ii<N;ii++){
g = gcd(arr[ii], g);
if(g==1){
break;
}
}
if(g==1){
System.out.println(0);
}else{
System.out.println(-1);
}
}
}
public static int gcd(int a, int b){
if(b==0){
return a;
}
return gcd(b, a%b);
}
}
2. 求a mod x = b的解的个数。90%
不知道哪里错了。。。
import java.util.*;
public class Main20200811002 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
long a = sc.nextLong();
long b = sc.nextLong();
if(a==b){
System.out.println("inf");
return ;
}
long t;
if(a-b>0){
t = a-b;
}else{
t = b-a;
}
int ans = 0;
long k = 1;
for(;t>k*b && t/k>=1;k++){ // 保证 x>b,x>=1 k越来越大,x越来越小
if(k>100000000){
System.out.println("inf");
return ;
}
if(t%k!=0){ // x不是整数
continue;
}
ans++; // x=t/k
}
System.out.println(ans);
}
}
3. 给定矩阵地图,有不可行点。自己选择起点或终点,问最短路径的最大值为多少。AC
遍历起点,对每个起点BFS
import java.util.*;
public class Main20200811003 {
static int H;
static int M;
static int[][] next = {{0,-1}, {-1,0}, {1,0}, {0,1}};
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
H = sc.nextInt();
M = sc.nextInt();
sc.nextLine();
char[][] table = new char[H][M];
for(int i=0;i<H;i++){
String line = sc.nextLine();
table[i] = line.toCharArray();
}
int ans = 0;
for(int x=0;x<H;x++){
for(int y=0;y<M;y++){
if(table[x][y]=='.'){
int tmp = bfs(x*100+y, table);
ans = Math.max(ans, tmp);
}
}
}
System.out.println(ans);
}
public static int bfs(int start, char[][] table){
int[][] isVis = new int[H][M];
LinkedList<Integer> pre = new LinkedList<>();
LinkedList<Integer> cur = new LinkedList<>();
cur.add(start);
isVis[start/100][start%100] = 1;
int ans = -1;
while(cur.size()>0){
ans++;
pre = cur;
cur = new LinkedList<>();
for(int pos: pre){
int x = pos/100;
int y = pos%100;
for(int i=0;i<4;i++){
int nx = x+next[i][0];
int ny = y+next[i][1];
if(nx>=0&&nx<H && ny>=0&&ny<M && isVis[nx][ny]==0 && table[nx][ny]=='.'){
cur.add(nx*100+ny);
isVis[nx][ny]=1;
}
}
}
}
return ans;
}
}
4. 4个人,每个人有一些音乐,给定所有音乐长度,选择若干首播放,并行播放时,最长结束时间和最短结束时间的差最小为多少。AC
暴力,首先得到每个人的所有播放时间长度,然后4个for循环,可过60%,加剪枝(如果当前时间差大于ans,就跳过)可过100%
import java.util.*;
public class Main20200811004 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] a = new int[4][n];
for(int i=0;i<4;i++){
for(int j=0;j<n;j++) {
a[i][j] = sc.nextInt();
}
}
int[] s0 = gen(a[0],n);
int[] s1 = gen(a[1],n);
int[] s2 = gen(a[2],n);
int[] s3 = gen(a[3],n);
int ans = Integer.MAX_VALUE;
int[] d = new int[4];
for(int i0=0;i0<s0.length;i0++){
d[0] = s0[i0];
for(int i1=0;i1<s1.length;i1++){
d[1] = s1[i1];
if(Math.abs(d[0]-d[1])>ans){
continue;
}
for(int i2=0;i2<s2.length;i2++){
d[2]= s2[i2];
if(Math.abs(d[0]-d[2])>ans){
continue;
}
if(Math.abs(d[1]-d[2])>ans){
continue;
}
for(int i3=0;i3<s3.length;i3++){
d[3] = s3[i3];
if(Math.abs(d[0]-d[3])>ans){
continue;
}
if(Math.abs(d[1]-d[3])>ans){
continue;
}
if(Math.abs(d[2]-d[3])>ans){
continue;
}
int minD = d[0], maxD = d[0];
for(int tt=0;tt<4;tt++){
if(d[tt]<minD) minD = d[tt];
if(d[tt]>maxD) maxD = d[tt];
}
int curAns = maxD - minD ;
ans = Math.min(ans, curAns);
}
}
}
}
System.out.println(ans);
}
public static int[] gen(int[] arr, int n){
ArrayList<Integer> ansl = new ArrayList<>();
for(int idx=0;idx<n;idx++){
int curn = ansl.size();
for(int i=0;i<curn;i++){
ansl.add(ansl.get(i)+arr[idx]);
}
ansl.add(arr[idx]);
}
ansl.sort((a,b)->(a-b));
int[] rst = new int[ansl.size()];
int len = 0;
int pre = -1;
for(int i=0;i<ansl.size();i++){
int cur = ansl.get(i);
if(pre==cur){
continue;
}else{
rst[len] = cur;
pre = cur;
len++;
}
}
return Arrays.copyOfRange(rst, 0, len);
}
}
