基础知识点
题
1.互质 - 蓝桥云课
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
long n = 2023L;
// 陶吉吉:欧拉~ 最近还好吗~~ oula~~ 怎么不说话~
// 欧拉函数:从1 到 n 有多少个与 n 互质的数字
long cnt = n;
for(long i = 2; i*i <= n; i++) {
if(n % i == 0) {
while(n % i == 0) {
n /= i;
}
cnt -= cnt/i;
}
// n本身就是一个质数
if(n > 1) {
cnt -= cnt/n;
}
}
long a = 2023L;
long b = 2022L;
long np = 1L;
long final MOD = 10000000007;
a %= MOD;
while(b > 0) {
if( (b&1) == 1) {
np = np*a % MOD;
}
b = b*b % MOD;
b >>= 1;
}
System.out.println(np*cnt);
scan.close();
}
}
首先是这个欧拉函数,要知道欧拉函数 φ(n)是求从1到n有多少个数与n互质的。
- 如果 n 是质数,φ(n) = n-1
- 如果 n = p^k(p是质数),φ(n) = φ(p^k) = p^(k-1) * p-1 = p^(k-1) * φ(p)
- 对于任意正整数,φ(ab) = φ(a)φ(b) (当a和b互质时)
φ(2023^2023) = 2023^2022 * φ(2023)
所以这题就是一个欧拉函数和快速幂的结合问题
欧拉函数模板
static void oula(long n) {
long res = n;
for(long i = 2; i*i <= n; i++) {
if(n % i == 0) {
// 去除所有 i 因子 就是 i 可以被 n 整除的数字。
while(n % i == 0) {
n /= i;
}
// res/i表示哪些能被i整除的数的数量,因为这些数与 n 不互质
// 我们从总数 res 中减去这些数,剩下的就是与 n 互质的数。
res -= res/i;
}
}
// 除了1以外,没有数字可以整除 n,说明数字 n 本身就是应该一个质数
if(n > 1) {
res -= res/n;
}
System.out.println(res);
}
快速幂模板
// 计算a^b
// 如果想让MOD不起作用,传入Long.MAX_VALUE
static void quickPow(long a, long b, long MOD) {
long res = 1L;
a %= MOD;
while(b > 0) {
if( (b&1) == 1) {
res = res * a % MOD;
}
a = a*a % MOD;
b >>= 1;
}
System.out.println(res);
}
2.玩具 - 蓝桥云课
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = n*2;
int[] nums = new int[m];
for(int i = 0; i < m; i++) {
nums[i] = scan.nextInt();
}
long res = 0L;
for(int i = 0; i < m; i++, m--) {
res += nums[i] * nums[m-1];
}
System.out.println(res);
scan.close();
}
}
这段代码的核心思想是一种贪心的想法。所有玩具零件重量排序后,最轻的与最重的一起,第二轻的与第二重的一起。因为大的数与大的数相乘会很大,所以让最大的数和最小的数字相乘,会是最最小的。
记得nums是整型数组,与res 进行运算的时候记得转换单位。
3.逆元 - 蓝桥云课
就是一个理解逆元,其实还是不是很理解。。。
4.不完整的算式 - 蓝桥云课
package com.lanqiao;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String input = scan.next();
String[] parts = input.split("=");
String left = parts[0];
String c = parts[1];
int opPos = -1;
char op = '?';
for(int i = 0; i < left.length(); i++) {
char ch = left.charAt(i);
if(ch == '+' || ch == '-'|| ch == '/' || ch == '*') {
opPos = i;
op = ch;
break;
}
}
String a = opPos!=-1 ? left.substring(0, opPos) : "?";
String b = opPos!=-1 ? left.substring(opPos+1, left.length()) : "?";
// 如果是op 被擦掉
if(opPos == -1) {
int t = left.indexOf('?');
// 是在左边
if(t != -1) {
a = left.substring(0, t);
b = left.substring(t+1, left.length());
}
}
// 如果是 c 被擦掉
if(c.equals("?")) {
int aNum = Integer.valueOf(a);
int bNum = Integer.valueOf(b);
int cNum = 0;
switch(op) {
case '+': cNum = aNum + bNum; break;
case '-': cNum = aNum - bNum; break;
case '*': cNum = aNum * bNum; break;
case '/': cNum = aNum / bNum; break;
}
System.out.println(cNum);
}
else if(b.equals("?")) {
int aNum = Integer.valueOf(a);
int cNum = Integer.valueOf(c);
int bNum = 0;
switch(op) {
case '+': bNum = cNum - aNum; break;
case '-': bNum = cNum + aNum; break;
case '*': bNum = cNum / aNum; break;
case '/': bNum = aNum / cNum; break;
}
System.out.println(bNum);
}
else if(a.equals("?")) {
int bNum = Integer.valueOf(b);
int cNum = Integer.valueOf(c);
int aNum = 0;
switch(op) {
case '+': aNum = cNum - bNum; break;
case '-': aNum = cNum + bNum; break;
case '*': aNum = cNum / bNum; break;
case '/': aNum = cNum * bNum; break;
}
System.out.println(aNum);
}
else if(op == '?') {
int aNum = Integer.valueOf(a);
int cNum = Integer.valueOf(c);
int bNum = Integer.valueOf(b);
if(aNum + bNum == cNum) {
System.out.println("+");
}
else if(aNum - bNum == cNum) {
System.out.println("-");
}
else if(aNum * bNum == cNum) {
System.out.println("*");
}
else if(aNum / bNum == cNum) {
System.out.println("/");
}
}
scan.close();
}
}
这个其实就是把逻辑理清楚
首先这个等式分为两个部分,等号左边和等号右边
在左边查找运算符的位置,如果等式左边不含有运算符,说明是运算符被擦掉了,如果是运算符被擦掉,那么就根据问号的位置重新分割出a和b
如果等式左边含有运算符,那么就根据运算符位置来分割a,b
5.星球 - 蓝桥云课
import java.util.*;
public class Main {
static double[][] dist;
static int[] w;
static Double[][] memo;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[][] coords = new int[n][3];
w = new int[n];
for(int i = 0; i < n; i++) {
coords[i][0] = scan.nextInt();
coords[i][1] = scan.nextInt();
coords[i][2] = scan.nextInt();
w[i] = scan.nextInt();
}
// 预计算所有星球的距离
dist = new double[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i != j) {
int dx = coords[i][0] - coords[j][0];
int dy = coords[i][1] - coords[j][1];
int dz = coords[i][2] - coords[j][2];
dist[i][j] = Math.sqrt(dx*dx + dy*dy + dz*dz);
}
}
}
// 初始化记忆数组
memo = new Double[n][1<<n];
// 尝试每个起点,取最小值
double minEnergy = Double.MAX_VALUE;
for(int start = 0; start < n; start++) {
double energy = tsp(start, 1 << start);
minEnergy = Marh.min(minEnergy, energy);
}
System.out.printf("%/2f", minEnergy);
}
static double tsp(int pos, int mask) {
if(mask == (1 << w.length) - 1) {
return
}
}
}