第一题:求数列差的最大公约数
题目描述:牛牛有一个长度为n的数组a,你要找到一个最大的正整数d,使得对于所有i(1<=i<=n),a[i+1]-a[i]是d的倍数。
输入:
第一行一个正整数n
第二行n个正整数
输出:
若d不存在,输出-1,否则输出最大的d
笔试时,忘了辗转相除法,没AC,看了网友思路后,写了如下代码,样例可过,不知能否AC
class Main1_2 {
public static void main(String[] args) {
// System.out.println(-6%3);
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
long a[] = new long[n];
long b[] = new long[n - 1];
long right = 0;
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt();
if (i != 0) {
b[i - 1] = a[i] - a[i - 1];
right = Math.max(right, b[i - 1]);
}
}
long num = b[0];
for (int i = 1; i < b.length; i++) {
num = gcd(num, b[i]);
}
System.out.print(num == 0 ? -1 : num);
}
public static long gcd(long num1, long num2) {
if (num2 == 0) return num1;
return gcd(num2, num1 % num2);
}
}
第二题:求牛牛消灭怪物最少承受的伤害
牛牛喜欢玩魔塔,魔塔中有n只怪物,每只怪物有两个属性:破防能力和伤害值,当勇者挑战一只怪物时,若
1,勇者防御力大于其破防能力,勇者不受伤害
2,否则勇者受等同于其伤害值的伤害
初始勇者伤害值为D,勇者可以按任意顺序挑战这n只怪物,每次挑战成功一只后可以获得防御力提升1点的奖励。
牛牛想知道,击败这n只怪兽最少需要承受多少伤害
输入:n,D,n个怪物的破防能力和伤害值(用两个数组输入)
输出:最少伤害值
这道题骗了数据,直接输出0,竟然过了60%。总感觉贪心不太对,就没敢写,放到最后没时间了。
看了一下网友思路:
- 如果有能不吃伤害打的,直接打
- 如果没有能不吃伤害打的,直接打破防最强的
第三题 感染者与聚会
并查集,AC
import java.util.Scanner;
/**
* Created by fangjiejie on 2020/4/7.
*/
public class Main3 {
static int father[] = null;
static int n;
public static void init() {
for (int i = 0; i < n; i++) {
father[i] = i;
}
}
public static int getFater(int x) {
int tmp = x;
while (tmp != father[tmp]) {
tmp = father[tmp];
}
father[x] = tmp;
return father[x];
}
public static void mix(int x, int y) {
int fa = getFater(x);
int fb = getFater(y);
if (fa != fb) {
father[fa] = fb;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
int m = scanner.nextInt();
int f = scanner.nextInt();
father = new int[n];
init();
for (int i = 0; i < m; i++) {
int num = scanner.nextInt();
int first = scanner.nextInt();
for (int j = 1; j < num; j++) {
int cur = scanner.nextInt();
mix(first, cur);
}
}
int count = 0;
int people = getFater(f);
for (int i = 0; i < n; i++) {
if (getFater(i) == people) {
count++;
}
}
System.out.println(count);
}
}
第四题 英雄与怪兽。更新二维数组中的值
n*m的地图上,每个位置值为0或1,0表示怪兽,1表示英雄,对于每个英雄求出离他最近的怪兽的距离是多少,矩阵中每个位置离上下左右的距离都是1,若当前位置是怪兽,输出0即可,题目保证至少存在一只怪兽
输入:第一行输入两个正整数 ,n,m
接下来n行,每行输入m个数,从{0,1}中取值。表示每个位置的属性,其中1<=m,n<=1000
例子:
3 3
101
010
101
输出更新后的矩阵。输出n行,每行m个用空格分隔的数字表示答案。注意行末没有空格
例子
1 0 1
0 1 0
1 0 1
笔试时写的代码只通过50%,提示超时
public class Main4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int a[][] = new int[n][m];
scanner.nextLine();
for (int i = 0; i < n; i++) {
String s = scanner.nextLine();
for (int j = 0; j < m; j++) {
a[i][j] = (int) (s.charAt(j) - '0');
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int tmp = 0;
if (a[i][j] == 1) {
visit = new boolean[n][m];
tmp = bfs(a, i, j, visit);
}
if (j != 0) System.out.print(" ");
System.out.print(tmp);
}
System.out.println();
}
}
static int dir[][] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
static boolean visit[][] = null;
private static int bfs(int[][] a, int i, int j, boolean[][] visit) {
Queue<Position> queue = new LinkedList<>();
Position position = new Position(i, j);
visit[i][j] = true;
queue.add(position);
int path = 0;
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- != 0) {
Position cur = queue.poll();
if (a[cur.x][cur.y] == 0) {
return path;
}
for (int k = 0; k < dir.length; k++) {
int x = cur.x + dir[k][0];
int y = cur.y + dir[k][1];
if (x < 0 || y < 0 || x >= a.length || y >= a[0].length || visit[x][y]) continue;
visit[x][y] = true;
queue.add(new Position(x, y));
}
}
path++;
}
return -1;
}
}
class Position {
int x;
int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
}
笔试后,了解到他人的思路,可以用多源bfs,下面是改进版,样例可以通过,不是能否ac
class Main4_2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int a[][] = new int[n][m];
int result[][] = new int[n][m];
boolean visit[][] = new boolean[n][m];
Queue<Position> queue = new LinkedList<>();
scanner.nextLine();
for (int i = 0; i < n; i++) {//从多个怪兽出发,然后最短能占领的就step
String s = scanner.nextLine();
for (int j = 0; j < m; j++) {
a[i][j] = (int) (s.charAt(j) - '0');
if (a[i][j] == 0) {
Position position = new Position(i, j);
queue.add(position);
}
}
}
int path = 0;
int dir[][] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- != 0) {
Position cur = queue.poll();
if (a[cur.x][cur.y] == 1) {
result[cur.x][cur.y] = path;
}
for (int k = 0; k < dir.length; k++) {
int x = cur.x + dir[k][0];
int y = cur.y + dir[k][1];
if (x < 0 || y < 0 || x >= a.length || y >= a[0].length || visit[x][y]) continue;
visit[x][y] = true;
queue.add(new Position(x, y));
}
}
path++;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j != 0) System.out.print(" ");
System.out.print(result[i][j]);
}
System.out.println();
}
}
}