2021全国高校计算机能力挑战赛决赛Java组
题目一
解法:模拟
代码如下
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] nums = new int[n];
double[] values = new double[n];
double avg = 0;
int N = 0;
for (int i = 0; i < n; i++) {
int x = scan.nextInt();
double y = scan.nextDouble();
nums[i] = x;
values[i] = y;
avg += x * y;
N += x;
}
avg /= N;
double res = 0.0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < nums[i]; j++) {
res += Math.pow((values[i] - avg), 2);
}
}
res /= N;
System.out.println((Math.round(Math.sqrt(res)*100))/100.0);
scan.close();
}
}
时间复杂度:O(n^2)
题目二
我做的那个操作一是乘3的,没看见操作二只能-1,以为能+1,比赛时使用错误贪心
解法:贪心
代码如下:
public class Main {
//2 17
// 18 - 1
//(((2 * 2 - 1) * 2 - 1) * 2 - 1) * 2 - 1
//
static int n, m;
public static int minMoves() {
if (n >= m) {
return n - m;
}
int ans = 0;
while (m != n) {
if (m % 2 == 0) {
if (m >= n * 2) {
m /= 2;
ans++;
} else {
ans += m - n;
m = n;
}
} else {
if (m > n) {
m += 1;
ans++;
}
}
}
return ans;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
m = scan.nextInt();
System.out.println(minMoves());
scan.close();
}
}
时间复杂度:O(log(abs(n - m)))
题目三
解法:模拟
代码如下:
import java.util.Scanner;
public class Main {
/*
* red blue red
* blue green blue
* red blue red
*/
static int n;
static String[][] arr = new String[3][3];
static {
for (int i = 0; i < 6; i++) {
arr[0][0] = "red";
arr[0][2] = "red";
arr[2][0] = "red";
arr[2][2] = "red";
arr[1][1] = "green";
arr[0][1] = "blue";
arr[1][0] = "blue";
arr[1][2] = "blue";
arr[2][1] = "blue";
}
}
//上右下左
static int[] dx = {-1,0,1,0};
static int[] dy = {0,1,0,-1};
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
//W R D L 上右下左
//0 1 2 3
int status = 0;
int x = 1, y = 1;
for (int i = 0; i < n; i++) {
String s = scan.next();
if (s.equals("L")) {
status = (status + 3) % 4;
} else if (s.equals("R")) {
status = (status + 1) % 4;
} else {
x += dx[status];
y += dy[status];
x = (x + 3) % 3;
y = (y + 3) % 3;
}
}
System.out.println(arr[x][y]);
scan.close();
}
}
时间复杂度:O(n)
题目四
解法:组合数 - 归并排序求逆序对 - 相同数对个数
代码如下:
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
static int n;
static int[] tmp = new int[100010];
private static long mergeSort(int[] arr, int l, int r) {
if(l >= r) return 0;
int mid = l + r >> 1;
long res = mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while(i <= mid && j <= r){
if(arr[i] <= arr[j]){
tmp[k++] = arr[i++];
}else{
res += mid - i + 1;
tmp[k++] = arr[j++];
}
}
while(i <= mid) tmp[k++] = arr[i++];
while(j <= r) tmp[k++] = arr[j++];
for(i = l, j = 0; i <= r; i++, j++) arr[i] = tmp[j];
return res;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
String num = scan.next();
int parseInt = Integer.parseInt(num, 16);
arr[i] = parseInt;
}
//动态规划求相等数对个数
int enp = 0;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : arr) {
if (map.containsKey(num)) {
enp += map.get(num);
map.put(num, map.get(num) + 1);
} else {
map.put(num, 1);
}
}
System.out.println(n * (n - 1) / 2 - mergeSort(arr, 0, n - 1) - enp);
scan.close();
}
}
时间复杂度:O(nlogn)
题目五
我那道是求小明省了多少次
解法:模拟
代码如下:
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
public class Main {
static int n, m;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
m = scan.nextInt();
Set<Integer> set = new HashSet<>();
List<Integer> list = new LinkedList<>();
int res = 0;
for (int i = 0; i < n; i++) {
int num = scan.nextInt();
if (set.add(num)) {
list.add(num);
} else {
res++;
}
if (list.size() == m + 1) {
set.remove(list.remove(0));
}
}
System.out.println(res);
scan.close();
}
}
时间复杂度:O(n)