PAT习题集

1001 A+B Format (20分)

import java.io.*;
import java.util.*;
class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken()), b = Integer.parseInt(st.nextToken());
        int sum = a + b, abs = Math.abs(sum);
        LinkedList<String> res = new LinkedList<>();
        int count = 0;  //已经插入的位数
        while(abs != 0){
            int digit = abs % 10;
            res.add(0, Integer.toString(digit));    //每次将当前最低位插入链表的头部
            count++;
            if(count % 3 == 0 && abs >= 10){    //abs >= 10保证之后仍有数字插入
                res.add(0, ",");
            }
            abs /= 10;
        }
        if(res.size() == 0) //没有插入数字,说明两数之和为0
            res.add("0");
        if(sum < 0){
            res.add(0, "-");
        }
        for (String e : res) {
            System.out.print(e);
        }
    }
}

1002 A+B for Polynomials (25分)

import java.io.*;
import java.util.*;
class Main{
    public static void main(String[] args) throws IOException {
        List<Double> list = new LinkedList<>(); //链表中的多项式格式:coe1, exp1, coe2, exp2, coe3, exp3, ...
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        st.nextToken(); //丢弃项数K
        while(st.hasMoreTokens()){
            list.add(Double.valueOf(st.nextToken()));
        }
        st = new StringTokenizer(br.readLine());
        st.nextToken(); //丢弃项数K
        int i = 0;
        while (st.hasMoreTokens()) {
            double exp = Double.parseDouble(st.nexKtToken());
            double coe = Double.parseDouble(st.nextToken());
            while (i < list.size() && exp < list.get(i)) {  //找到插入或者合并的位置
                i += 2;
            }
            if (i >= list.size() || exp != list.get(i)) {
                list.add(i, coe);
                list.add(i, exp);
                i += 2;
            } else {
                double newCoe = list.remove(i + 1) + coe;
                if (newCoe == 0) {
                    list.remove(i); //两项相加系数为零,直接删掉
                } else {
                    list.add(i + 1, newCoe);    //将求和后的系数插入
                }
            }
        }
        if(list.size() == 0){
            System.out.println("0");
            return;
        }
        System.out.print(list.size() / 2 + " ");
        for (int j = 0; j < list.size(); j++) {
            double temp = list.get(j);
            if (j % 2 == 0) {
                System.out.print((int) temp + " ");
            } else {
                System.out.print(Math.ceil(temp * 10) / 10);
                if(j != list.size() - 1)
                    System.out.print(" ");
            }
        }
    }
}

1003 Emergency (25分)

dfs

题目给出各城市救援队数,相当于图的点权;给出城市之间的路径长,即边权。选择用邻接矩阵记录图中各顶点的联系。

可以利用深度优先搜索找目的地,如果遇到更短的路径,则更新:

  • 最短路径长
  • 到达路径数更新为1
  • 最大可以搜集的救援队数

如果遇到和当前最短路径一样短的路径,则更新:

  • 可以到达的路径数+1
  • 判断是否需要更新最大可以搜集的救援队数

其它:

  • 为了避免递归时在环路上绕圈,设置一个数组标志哪些顶点已经走过,避免dfs无限递归下去。
  • 为了省去冗余计算,如果当前的路径长已经大于最短路径长了,直接让方法返回,即对递归进行剪枝。
import java.util.Scanner;

public class Main {

    private static boolean[] visited;
    private static int[] weight;
    private static int[][] map;
    private static int shortestPathCount;
    private static int shortestDist;
    private static int maxTeamCount;

    public static void main(String[] args) {
        //接收输入
        Scanner sc = new Scanner(System.in);
        int cityNum = sc.nextInt();
        int roadNum = sc.nextInt();
        int start = sc.nextInt();
        int destination = sc.nextInt();
        weight = new int[cityNum];
        int count = 0;
        while (count < cityNum) {
            weight[count] = sc.nextInt();
            count++;
        }
        map = new int[cityNum][cityNum];
        //初始化
        for (int i = 0; i < cityNum; i++) {
            for (int j = 0; j < cityNum; j++) {
                map[i][j] = -1;
            }
        }
        visited = new boolean[cityNum];
        count = 0;
        while (count < roadNum) {
            int c1 = sc.nextInt(), c2 = sc.nextInt();
            int dis = sc.nextInt();
            map[c1][c2] = dis;
            map[c2][c1] = dis;
            count++;
        }

        //初始化
        shortestPathCount = 0;
        shortestDist = Integer.MAX_VALUE;
        maxTeamCount = 0;

        findShortestPath(start, destination, 0, weight[start]);

        System.out.println(shortestPathCount + " " + maxTeamCount);
    }

    private static void findShortestPath(int start, int dest, int dist, int currentWeight) {
        if(dist > shortestDist) //剪枝
            return;
        if (start == dest) {
            if (dist < shortestDist) {
                maxTeamCount = currentWeight;
                shortestDist = dist;
                shortestPathCount = 1;
            } else if(dist == shortestDist) {
                shortestPathCount++;
                maxTeamCount = maxTeamCount > currentWeight? maxTeamCount: currentWeight;
            }
            return;
        }
        for (int i = 0; i < map[start].length; i++) {
            int nextDist = map[start][i];
            if (nextDist == -1 || visited[i])
                continue;
            visited[i] = true;
            findShortestPath(i, dest, dist + nextDist, currentWeight + weight[i]);
            visited[i] = false;
        }
    }
}

Dijkstra

遇到同样长度的最短路径时更新策略跟dfs方法类似,但Dijkstra最短路径的查找原理是贪心算法。

import java.util.*;
import java.io.*;
class Main {
    public static void main(String[] args) {
        //接收输入
        Scanner sc = new Scanner(System.in);
        int cityNum = sc.nextInt();
        int[][] map = new int[cityNum][cityNum];
        int[] distance = new int[cityNum];
        boolean[] visited = new boolean[cityNum];
        int roadNum = sc.nextInt();
        int initialCity = sc.nextInt();
        int destination = sc.nextInt();
        int[] weight = new int[cityNum];
        int index = 0;
        while(index < cityNum){
            weight[index] = sc.nextInt();
            index++;
        }

        for (int i = 0; i < cityNum; i++) {
            for (int j = 0; j < cityNum; j++) {
                map[i][j] = Integer.MAX_VALUE;
            }
        }
        index = 0;
        while(index < roadNum){
            int c1 = sc.nextInt(), c2 = sc.nextInt(), dis = sc.nextInt();
            map[c1][c2] = dis;
            map[c2][c1] = dis;
            index++;
        }

        //初始化
        for (int i = 0; i < cityNum; i++) {
            distance[i] = Integer.MAX_VALUE;
        }
        distance[initialCity] = 0;
        int[] roadCount = new int[cityNum];
        roadCount[initialCity] = 1;
        int[] maxWeight = new int[cityNum];
        maxWeight[initialCity] = weight[initialCity];
        //Dijkstra
        for (int i = 0; i < cityNum; i++) {
            int minDis = Integer.MAX_VALUE, u = -1;
            for (int j = 0; j < cityNum; j++) {
                if(!visited[j] && distance[j] < minDis){
                    minDis = distance[j];
                    u = j;
                }
            }
            if(u == -1)
                break;
            visited[u] = true;
            for (int v = 0; v < cityNum; v++) {
                int nextDis = map[u][v];
                if(nextDis == Integer.MAX_VALUE || visited[v])
                    continue;
                if(distance[u] + nextDis < distance[v]){
                    distance[v] = nextDis + distance[u];
                    roadCount[v] = roadCount[u];
                    maxWeight[v] = maxWeight[u] + weight[v];
                } else if(distance[u] + nextDis == distance[v]){
                    roadCount[v] += roadCount[u];
                    maxWeight[v] = Math.max(maxWeight[v], maxWeight[u] + weight[v]);
                }
            }
        }
        System.out.println(roadCount[destination] + " " + maxWeight[destination]);
    }
}
发布了61 篇原创文章 · 获赞 0 · 访问量 821

猜你喜欢

转载自blog.csdn.net/weixin_43116322/article/details/103795380