PAT基础编程题目集----4

大家有什么疑问可以在评论区评论,一起交流进步啊o(∩_∩)o

字符串循环左移
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        int length = string.length();
        int frequency = length;
        int n = scanner.nextInt() % length;
        char[] chars = string.toCharArray();
        for (int i = n; frequency-- > 0; i = ++i % length) {
            System.out.print(chars[i]);
        }
    }
}

字符串左移相当于指针右移,移动了多少次可以直接从下标开始输出所有的字符就行了。

说反话-加强版
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String sentence = scanner.nextLine().trim();
        String[] words = sentence.split("\\s+");
        StringBuilder builder = new StringBuilder();
        for (int i = words.length - 1; i >= 0; i--) {
            builder.append(words[i]).append(" ");
        }
        System.out.print(builder.toString().trim());
    }
}

这个简单的最后一个测试过不了,超时!!

port java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String sentence = scanner.nextLine();
        char[] chars = sentence.toCharArray();
        //这里可以变成链表
        ArrayList<String> list = new ArrayList<>();
        ArrayList<Character> word = new ArrayList<>();
        for (int i = 0; i < chars.length; i++) {
            if (' ' == chars[i]) {
                continue;
            }
            word.add(chars[i]);
            if (i + 1 > chars.length) {
                break;
            }
            if (i + 1 == chars.length) {
                String w = Main.charList2String(word);
                list.add(w);
                break;
            }
            if (chars[i + 1] == ' ') {
                String w = Main.charList2String(word);
                list.add(w);
                word.clear();
            }
        }
        StringBuilder result = new StringBuilder();
        for (int i = list.size() - 1; i >= 0; i--) {
            result.append(list.get(i)).append(" ");
        }
        System.out.print(result.toString().trim());
    }

    private static String charList2String(ArrayList<Character> chars) {
        StringBuilder builder = new StringBuilder();
        for (Character a : chars) {
            builder.append(a);
        }
        return builder.toString();
    }
}

MD这个也超时……我觉得我这个算法可以了,复杂度O(n),不知道为什么过不了?

有理数加法
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] nums = scanner.nextLine().split(" ");
        String[] a = nums[0].split("/");
        String[] b = nums[1].split("/");
        int molecule = Integer.valueOf(a[0]) * Integer.valueOf(b[1]) + Integer.valueOf(b[0]) * Integer.valueOf(a[1]);
        int denominator = Integer.valueOf(a[1]) * Integer.valueOf(b[1]);
        int min = molecule > denominator ? denominator : molecule;
        for (int i = 2; i <= min; i++) {
            if (molecule % i == 0 && denominator % i == 0) {
                molecule /= i;
                denominator /= i;
                min = molecule > denominator ? denominator : molecule;
                i = 1;
            }
        }
        System.out.print(molecule);
        if (denominator != 1) {
            System.out.print("/" + denominator);
        }
    }

}

里面用到了求最大公约数的算法,总体上比较简单

通讯录的录入与显示
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<String> people = new ArrayList<>();
        int N = scanner.nextInt();
        for (int i = 0; i <= N; i++) {
            String s = scanner.nextLine();
            people.add(s);
        }
        //这里不知道为什么循环读取数据会读取一个空字符串,我也不太想研究为什么,直接删除就好。
        people.remove(0);
        String[] index = scanner.nextLine().split(" ");
        Integer selectNum = Integer.valueOf(index[0]);
        for (int i = 1; i <= selectNum; i++) {
            if (Integer.valueOf(index[i]) < 0 || Integer.valueOf(index[i]) >= N) {
                System.out.println("Not Found");
            } else {
                String target = people.get(Integer.valueOf(index[i]));
                String[] fields = target.split(" ");
                System.out.println(fields[0] + " " + fields[3] + " " + fields[4] + " " + fields[2] + " " + fields[1]);
            }
        }
    }

}

没注意到输出字段的顺序不一样,我一看一个都没过,当时就懵逼了

有理数均值
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        String[] nums = scanner.nextLine().split(" ");
        long[][] tem = new long[n][2];
        //取数
        for (int i = 0; i < nums.length; i++) {
            String[] split = nums[i].split("/");
            tem[i][0] = Long.parseLong(split[0]);
            tem[i][1] = Long.parseLong(split[1]);
        }
        //求和
        for (int i = 1; i < n; i++) {
            tem[0] = plus(tem[0], tem[i]);
        }
        //最终化简
        long[] result = simplify(tem[0][0], tem[0][1] * n);
        System.out.print(result[0]);
        if (result[1] != 1) {
            System.out.print("/" + result[1]);
        }
    }


    private static long[] plus(long[] a, long[] b) {
        long molecule = a[0] * b[1] + b[0] * a[1];
        long denominator = a[1] * b[1];
        return simplify(molecule, denominator);
    }

    private static long[] simplify(long molecule, long denominator) {
        long min = molecule > denominator ? denominator : molecule;
        for (long i = 2; i <= min; i++) {
            if (molecule % i == 0 && denominator % i == 0) {
                molecule /= i;
                denominator /= i;
                min = molecule > denominator ? denominator : molecule;
                i = 1;
            }
        }
        return new long[]{molecule, denominator};
    }
}

这个过不了测试点3,最大N错误,我不懂哪里有问题……

复数四则运算
import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double a = scanner.nextDouble();
        double b = scanner.nextDouble();
        double c = scanner.nextDouble();
        double d = scanner.nextDouble();
        //加
        double m = a + c;
        double n = b + d;
        output(a, b, c, d, m, n, "+");
        //减
        m = a - c;
        n = b - d;
        output(a, b, c, d, m, n, "-");
        //乘
        m = a * c - b * d;
        n = b * c + a * d;
        output(a, b, c, d, m, n, "*");
        //除
        m = (a * c + b * d) / (c * c + d * d);
        n = (b * c - a * d) / (c * c + d * d);
        output(a, b, c, d, m, n, "/");
    }

    private static void output(double a, double b, double c, double d, double m, double n, String op) {
        //这里可以自己封装一个四舍五入的方法
        BigDecimal t1 = new BigDecimal(m);
        m = t1.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
        BigDecimal t2 = new BigDecimal(n);
        n = t2.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
        System.out.printf("(%.1f%+.1fi) %s (%.1f%+.1fi) = ", a, b, op, c, d);
        if (m == 0 && n == 0) {
            System.out.println("0.0");
        } else if (m != 0 && n == 0) {
            System.out.printf("%.1f\n", m);
        } else if (m == 0 && n != 0) {
            System.out.printf("%.1fi\n", n);
        } else {
            System.out.printf("%.1f%+.1fi\n", m, n);
        }
    }
}
整数分解为若干项之和
import java.util.Scanner;

public class Main {
    private static int sum = 0;
    private static int count = 0;
    private static int n = 0;
    private static int[] num = new int[30];
    private static int top = -1;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        dfs(1);
    }

    private static void dfs(int j) {
        if (sum < n) {
            for (int i = j; i <= n; i++) {
            	//下面这几句意思是:把当前坑位的值用dfs检测一下。
                num[++top] = i;//把i放在当前坑位里面
                sum += i;//把当前坑位的值加到sum里面,等价于sum=num[top]
                dfs(i);//看看sum对不对
                sum -= i;//把sum的值恢复原状
                top--;//这里的--配合下次循环刚开始的++,两个操作合起来表示top的值没有便,现在考虑的还是这个坑位
            }
        } else if (sum == n) {
            count++;
            System.out.printf("%d=", n);
            int k;
            for (k = 0; k < top; k++) {
                System.out.printf("%d+", num[k]);
            }
            if (count % 4 == 0 || num[top] == n) {
                System.out.printf("%d\n", num[top]);
            } else {
                System.out.printf("%d;", num[top]);
            }
        }
    }
}

这个难到我了,网上都说是深度优先算法,我一开始理解不来这个怎么和DFS联系起来。强行理解了一下感觉效果一点都不好,也是一边抄别人的代码一边思考,慢慢有了思路。

这个题就和解二元一次方程似的,从1开始一个一个数字试。输入n,那就有n个坑位,每个坑位都从1开始往上加。

先不在dfs方法里面传参数,j固定等于1,如果n等于7,那么代码的意思就是,前6个坑位都是1,第七个坑位从1到n挨个试了一遍,试了一遍指的是第七个坑位里面的每一个值都调用了一次dfs方法,实际上只有第七个坑位里面是1的时候,dfs里面会判断相等,第七个坑位是2、3、4、5、6、7的时候,sum的值都大于n所以没有再到下一个坑位。

第七个坑位全部试过之后,就回到了第六个坑位,第一次到第六个坑位的时候,把第六个坑位的值设置成了1,然后调用了dfs方法,因为sum是6小于7,所以进到了第七个坑位,现在从第七个坑位回来的时候,第六个坑位就该变成2了。这时候前5个坑位是1,第六个坑位是2,sum是7,所以第六个坑位是2的时候调用dfs,会判断输出,输出之后又回到第六个坑位,第六个坑位变成3、4、5、6、7,第六个坑位的这些值都要让sum在dfs里面走一遭。以此类推。

如果不在dfs里面传参会有一个小问题,按照上述的方式想象一下就会发现,在前4个坑位都是1,第五个坑位是2,的时候第六个坑位要是从1开始测试的话,就会出现 1 1 1 1 2 1的情况,这种情况也是7的分解式子,但是和要求的输出不一样,要保证后面的坑位里面的数字要比前面的坑位的数字大才行。也就是第五个坑位里面数字是2的时候,要告诉第六个坑位:不要从1开始循环了,从2开始循环吧。也就是后面这个坑位要从几开始循环,是由前面的坑位循环到几决定的,也就是为什么要给dfs传值。

这道题如果明确的知道n是多少,可以写一个n重循环来解决。因为不知道n是多少,所以用了递归来做。

这个题我刚开始一点头绪都没有,对我来说难度比较大,我能理解dfs算法,但是我无法把这道题和dfs算法联系起来,当我慢慢搞懂这道题的时候,我才把握到它和dfs算法的相似之处。一个坑位就相当于一个节点,每个坑位有n个数要测试,就代表有n条分支,用某个数测试就表示进入某个分支。每个节点有n个分支,n个节点就有n的n次方个分支,分支很多,但是也有很多分支是可以通过内部逻辑判断而不去执行的。这道题有点寻路的感觉,找出符合条件的某几个节点。

数列求和-加强版
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int n = scanner.nextInt();
        if (n == 0){
            System.out.println(0);
            return;
        }
        int[] num = new int[n];
        ArrayList<Integer> list = new ArrayList<>();
        int flag = 0;
        for (int i = n; i > 0; i--) {
            int r = i * a + flag;
            list.add(r % 10);
            flag = r / 10;
        }
        for (int i = list.size(); i > 0; i--) {
            System.out.print(list.get(i - 1));
        }
    }

}

一开始毫无疑问的超时,看了网上的答案知道了要一位一位的加,倒是不难理解,但是过不了最后的测试,我测了一下360多毫秒,抄了一百多毫秒,十有八九是Java的锅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值