CSP202212 03.18 JAVA 现值计算 训练计划 JPEG解码 聚集方差 星际网络 持续更新欢迎交流..

目录

当前结果

现值计算

训练计划

JPEG 解码

聚集方差

星际网络


更新时间:2023.03.18

当前结果

 

题目地址:首页 - 计算机软件能力认证考试系统

注意:想直接运行需要把下列代码class名和main函数改成Main再加入即可

现值计算

思路

按题目模拟即可

代码

import java.util.*;

public class xzjs20221201 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int n = scan.nextInt();
        double i = scan.nextDouble();
        int[] a = new int[n + 1];
        double res = 0;
        for (int x = 0; x <= n; x++) {
            a[x] = scan.nextInt();
            res += a[x] * Math.pow(1 + i, -x);
        }
        System.out.printf("%.3f", res);
        scan.close();
    }
}

训练计划

思路

假定箭头指向为爸爸,箭头指出为儿子 

  1. 接收输入
  2. 先处理最早开始时间
    1. 如果项目无爸爸,最早开始时间为1
    2. 如果有依赖
      1. 最早时间为爸爸j最早时间+j耗时
      2. 如果当前最早时间+本身i耗时超过n则说明完成不了
      3. j儿子列表加入i
  3. 输出最早开始时间,如果完成不了则直接退出否则下一步
  4. 倒叙遍历
    1. 默认最晚从n+1减当前项i耗时算
    2. 找儿子们的最晚时间的最早项,用这个减当前项耗时即为当前最晚耗时
  5. 输出最晚开始时间

代码

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class xljh20221202 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt(), m = scan.nextInt();
        int[] p = new int[m];
        for (int i = 0; i < m; i++) {
            p[i] = scan.nextInt();
        }
        int[] t = new int[m];
        for (int i = 0; i < m; i++) {
            t[i] = scan.nextInt();
        }
        int[] pre = new int[m];
        int[] last = new int[m];
        List<List<Integer>> fromList = new ArrayList<>();
        boolean isPrint2 = true;
        for (int i = 0; i < m; i++) {
            if (p[i] == 0) {
                pre[i] = 1;
            } else {
                int j = p[i] - 1;
                pre[i] = pre[j] + t[j];
                if (pre[i] + t[i] - 1 > n) isPrint2 = false;
                List<Integer> from = fromList.get(j);
                from.add(i);
            }
            fromList.add(new ArrayList<>());
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < m - 1; i++) {
            sb.append(pre[i]).append(' ');
        }
        System.out.println(sb.append(pre[m - 1]));
        if (isPrint2) {
            for (int i = m - 1; i >= 0; i--) {
                int min = n + 1;
                for (int f : fromList.get(i)) {
                    min = Math.min(min, last[f]);
                }
                last[i] = min - t[i];
            }
            sb = new StringBuilder();
            for (int i = 0; i < m - 1; i++) {
                sb.append(last[i]).append(' ');
            }
            System.out.println(sb.append(last[m - 1]));
        }
        scan.close();
    }
}

JPEG 解码

思路

模拟即可

扫描数据思路:

按照箭头方向扫,注意如果i>7的情况处理。

代码

import java.util.Scanner;

public class jpeg20221203 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int[][] matrix = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                matrix[i][j] = scan.nextInt();
            }
        }
        int n = scan.nextInt(), T = scan.nextInt();
        // 第三步
        int[][] m = new int[8][8];
        int index = 0;
        for (int i = 0; i < 15 && index < n; i++) {
            int a, b;
            // 右上
            if (i % 2 == 0) {
                a = i > 7 ? 7 : i;
                b = i - a;
                while (index < n && a >= 0 && b <= 7) {
                    m[a--][b++] = scan.nextInt();
                    index++;
                }
            }
            // 左下
            else {
                b = i > 7 ? 7 : i;
                a = i - b;
                while (index < n && b >= 0 && a <= 7) {
                    m[a++][b--] = scan.nextInt();
                    index++;
                }
            }
        }
        if (T == 0) {
            for (int i = 0; i < 8; i++) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < 8; j++) {
                    sb.append(m[i][j]).append(" ");
                }
                System.out.println(sb);
            }
            scan.close();
            return;
        }
        // 第四步
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                m[i][j] *= matrix[i][j];
            }
        }
        if (T == 1) {
            for (int i = 0; i < 8; i++) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < 8; j++) {
                    sb.append(m[i][j]).append(' ');
                }
                System.out.println(sb);
            }
            scan.close();
            return;
        }

        // 第五步
        double[][] m5 = new double[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                double temp = 0.0;
                for (int u = 0; u < 8; u++) {
                    for (int v = 0; v < 8; v++) {
                        double a = u == 0 ? Math.sqrt(0.5) : 1, b = v == 0 ? Math.sqrt(0.5) : 1;
                        double cos = Math.cos(Math.PI / 8 * (i + 0.5) * u) * Math.cos(Math.PI / 8 * (j + 0.5) * v);
                        temp += (a * b * m[u][v] * cos);
                    }
                }
                temp *= 0.25;
                m5[i][j] = temp;
            }
        }
        // 第六步
        int[][] m6 = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                m6[i][j] = (int) Math.round(m5[i][j] + 128);
                if (m6[i][j] > 255) m6[i][j] = 255;
                else if (m6[i][j] < 0) m6[i][j] = 0;
            }
        }
        if (T == 2) {
            for (int i = 0; i < 8; i++) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < 8; j++) {
                    sb.append(m6[i][j]).append(' ');
                }
                System.out.println(sb);
            }
            scan.close();
        }
    }
}

聚集方差

感觉做的思路没问题,但是没得分,欢迎指出问题

思路

初始时,各节点的子树节点只有自身。

逆序遍历,将后序节点的所有子树节点集合加入到前序节点的子树集合中。

对各子树按偏好时间进行排序,求相邻节点最小时间差的平方和。

代码

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class jjfc20221204 {
    // id a set T res
    private static int[] res;
    private static int[][] Ts;
    private static Set<Integer>[] sets;
    private static int[] a;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        init(n);
        for (int i = 1; i <= n; i++) {
            sets[i] = new HashSet<>();
            sets[i].add(i);
            Ts[i][1] = i;
            Ts[i][0] = 1;
        }

        // 每个员工的老板
        int[] p = new int[n + 1];
        for (int i = 2; i <= n; i++) {
            p[i] = scan.nextInt();
        }

        // 逆序遍历,将后序节点的所有子树节点集合加入到前序节点的子树集合中。
        for (int i = n; i >= 2; i--) {
            addSons(p[i], i);
        }
        // 每个员工偏好时间
        for (int i = 1; i <= n; i++) {
            a[i] = scan.nextInt();
        }
        // 所有节点子节点按照a的大小排序
        for (int i = 1; i <= n; i++) {
            getRes(i);
            System.out.println(res[i]);
        }
        scan.close();
    }

    private static void getRes(int id) {
        int size = Ts[id][0];
        Integer[] T = new Integer[size];
        for (int i = 0; i < size; i++) {
            T[i] = Ts[id][i + 1];
        }
        Arrays.sort(T, (o1, o2) -> a[o1] - a[o2]);
        if (size == 1) {
            res[id] = 0;
            return;
        }
        int ans = 0;
        int m0 = a[T[0]] - a[T[1]];
        ans += m0 * m0;
        for (int i = 1; i < size - 1; i++) {
            int m = a[T[i]] - a[T[i - 1]];
            int n = a[T[i]] - a[T[i + 1]];
            ans += Math.min(m * m, n * n);
        }
        int ml = a[T[size - 2]] - a[T[size - 1]];
        ans += ml * ml;
        res[id] = ans;
    }

    private static void init(int n) {
        int len = n + 1;
        res = new int[len];
        // 0 儿子数量 1 自己 后续:儿子们
        Ts = new int[len][len];
        sets = new HashSet[len];
        a = new int[len];
    }

    private static void addSons(int fa, int son) {
        int sSize = Ts[son][0];
        int fSize = Ts[fa][0];
        for (int i = 1; i <= sSize; i++) {
            int grandSon = Ts[son][i];
            Set<Integer> set = sets[fa];
            if (set.add(grandSon)) {
                Ts[fa][++fSize] = grandSon;
            }
        }
        Ts[fa][0] = fSize;
    }
}

星际网络

感觉做的思路没问题,但是只得了20分,欢迎指出问题

目前感觉错误原因有超时,以及星际时间存在超限制的情况未处理

思路

Dijkstra(迪杰斯特拉)算法

注意响应时间用long存放(仍存在超限情况)

代码

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
    private long[] d;// 从起始开始经过其他节点
    private long[] re;
    private Set<Integer> set;
    private int n, m;
    private int[][] datas;
    private int mo = (int) Math.pow(10, 9) + 7;
    private long[] ts;

    public static void main(String[] args) {
        new Main().solution();
    }

    public void solution() {
        init();
        djikD();
        clear();
        djikR();
        print();
    }

    private void clear() {
        set = new HashSet<>();
    }

    private void djikR() {
        // 所有星球都遍历
        if (set.size() == n) return;
        // 找最小点
        int minId = 0;
        long min = Long.MAX_VALUE;
        for (int i = 1; i <= n; i++) {
            if (set.contains(i)) continue;
            if (re[i] < min) {
                minId = i;
                min = re[i];
            }
        }
        // 从该点出发 找最小路径
        for (int i = 1; i <= m; i++) {
            // 遍历中继卫星 中继卫星可用
            if (datas[i][2] <= minId && minId <= datas[i][3]) {
                int l = datas[i][0], r = datas[i][1];
                long temp = min + ts[i];
                // 使用该中继卫星
                for (int j = l; j <= r; j++) {
                    // 更新d
                    if (temp < re[j]) re[j] = temp;
                }
            }
        }
        // 加入处理队列
        set.add(minId);
        djikR();
    }

    private long getT(int a, int b) {
        long t = a;
        while (b-- > 0) {
            t <<= 1;
        }
        return t;
    }

    private void print() {
        StringBuilder sb = new StringBuilder();
        for (int i = 2; i <= n; i++) {
            if (d[i] == Long.MAX_VALUE || re[i] == Long.MAX_VALUE) sb.append(-1).append(' ');
            else sb.append((d[i] + re[i]) % mo).append(' ');
        }
        System.out.println(sb);
    }

    private void djikD() {
        // 所有星球都遍历
        if (set.size() == n) return;
        // 找最小点
        int minId = 0;
        long min = Long.MAX_VALUE;
        for (int i = 1; i <= n; i++) {
            if (set.contains(i)) continue;
            if (d[i] < min) {
                minId = i;
                min = d[i];
            }
        }
        // 从该点出发 找最小路径
        for (int i = 1; i <= m; i++) {
            // 遍历中继卫星 中继卫星可用
            if (datas[i][0] <= minId && minId <= datas[i][1]) {
                int l = datas[i][2], r = datas[i][3];
                long temp = min + ts[i];
                // 使用该中继卫星
                for (int j = l; j <= r; j++) {
                    // 更新d
                    if (temp < d[j]) d[j] = temp;
                }
            }
        }
        // 加入处理队列
        set.add(minId);
        djikD();
    }

    public void init() {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        m = scan.nextInt();
        datas = new int[m + 1][6];
        ts = new long[m + 1];
        for (int i = 1; i <= m; i++) {
            for (int j = 0; j < 6; j++) {
                datas[i][j] = scan.nextInt();
            }
            ts[i] = getT(datas[i][4], datas[i][5]);
        }
        d = new long[n + 1];
        re = new long[n + 1];
        Arrays.fill(d, Long.MAX_VALUE);
        Arrays.fill(re, Long.MAX_VALUE);
        d[1] = 0;
        re[1] = 0;
        set = new HashSet<>();
        scan.close();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值