特辣的海藻!16

基础知识点 
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 
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值