ACM模式归纳总结

ACM pattern

  • 注意类名必须为 Main, 不要有任何 package xxx 信息

1.输入与输出

1. 单个输入与单行输入

输入一个数,或者字符串,或者一行数中间用空格隔开:

1.1输入一个数
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        
        System.out.println(num);

    }
}

byte/ double/ float/ int/ long/ short 类型的类似:

nextDouble();
nextByte();
nextLong();
nextBoolean();
1.2输入一个字符串
next()、nextLine()都可以:
不过要注意 
next()不会吸取字符前后的空格/Tab键,只吸取字符,开始吸取字符(字符前后不算)直到遇到空格/Tab键/回车截止吸取;
nextLine()吸取字符前后的空格/Tab键,回车键截止。


String str1 = sc.next(); //接收第1个值
String str2 = sc.nextLine(); //接收的是一整行

1.3输入一个char类型字符

Scanner本身并不支持获取char类型的数据,但是可以通过charAt()方法截取string的首位来获取char类型的数据。

char c = scanner.next().charAt(0);

输入一行数据or字符串,中间用空格隔开
对于不同数据类型的方法都类似,连续用几次next()或者nextInt()函数:

String a = sc.next();// 接收第1个值
 String b = sc.next();// 接收第2个值
 String c = sc.next();// 接收第3个值

2.多行输入

2.1给出了矩阵的行列数,用for遍历
第一行是两个用空格隔开的正整数n与m,n为行数,m为列数。
接下来的n行,每行是m个用空格隔开的正整数。如:
2 3
5 6 8
1 6 9
想要用二维数组接收:

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //用二维数组接收:
        int m = in.nextInt();
        int n = in.nextInt();
        int[][] nums = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                nums[i][j] = in.nextInt();
                System.out.print(nums[i][j]);
            }
        }
    }
}

注意在验证的时候,分隔号一定要用双引号隔开,单引号字符会参与计算!!

2.2没有给出具体的行列数,用hasNextLine()判断
有些输入可能是:
输入一个矩阵,每行以空格分隔。
1 2 3
56 8 2 9
对于这种没有给定矩阵行列数的输入,我们只能按照字符串拆分来进行。

Integer.parseInt(s)的作用就是把字符串s解析成有符号的int基本类型。

        String s1 = "1000";
        String s2 = "1000";
        int n1 = Integer.parseInt(s1);
        int n2 = Integer.parseInt(s2);
        if (n1 == n2) {         System.out.println("Integer.parseInt(s1) == Integer.parseInt(s2)");
        }

Integer.valueOf(s)把字符串s解析成Integer对象类型,返回的integer 可以调用对象中的方法。

        String s = "123";
        Integer integer = Integer.valueOf(s);
        System.out.println("integer : " + integer);

联系:
这里提一下parseInt()valueOf()的区别:
Integer.parseInt(str)返回值是int型的;
Integer.valueOf(str)返回值是Integer型的。

但是

Integer.parseInt(s)是把字符串解析成int基本类型,Integer.valueOf(s)是把字符串解析成Integer对象类型,其实int就是Integer解包装,Integer就是int的包装,在jdk8中已经自动实现了自动解包装和自动包装,所以两种方式都能得到想要的整数值。

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        List<List<Integer>> list = new ArrayList<>();
        while (in.hasNextLine()) {
            List<Integer> line = new ArrayList<>();
            String str = in.nextLine();
            String[] arr = str.split(" ");
            for (String s : arr) {
                line.add(Integer.valueOf(s));
            }
            list.add(line);
        }
        System.out.println(list);
    }
}

2.3输入数组中带有中括号和逗号
有些输入可能是,输入一个矩阵:
[[3,2,3],
[1,6,5],
[7,8,9]]
对于这种没有给定矩阵行列数的输入,而且还包含中括号和逗号的输入,我们也是只能按照字符串拆分来进行。这里逗号和右中括号是关键。
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        List<List<Integer>> list = new ArrayList<>();
        while (in.hasNextLine()) {
            List<Integer> line = new ArrayList<>();
            String str = in.nextLine();
            //只要改这里就可以,加几个replace()
            //string.replace(char oldChar, char newChar)
            //replace()方法用 新的字符/文本 替换字符串中每个匹配的旧字符/文本。
            String[] arr = str
                    .replace("[", "")
                    .replace("]", "")
                    .replace("],", "")
                    .replace(" ", "")
                    .split(",");
            for (String s : arr){
                line.add(Integer.valueOf(s));
            }
            list.add(line);
        }
        System.out.println(list);
    }
}

3.解析逗号分隔符的字符串

输入用逗号分隔的字符串: 1,5,9,6,5,7,2
想要接收后变成int类型数组:

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = in.next();
        String[] arr = str.split(",");
        int[] nums = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            nums[i] = Integer.parseInt(arr[i]);
            System.out.print(nums[i]);
        }
    }
}

4.输出写法

//换行打印,输出之后会自动换行
System.out.println();
//不换行打印
System.out.print();
//按格式输出
System.out.printf();

对于printf

/*** 输出字符串 ***/
// %s表示输出字符串,也就是将后面的字符串替换模式中的%s
System.out.printf("%s", new Integer(1212));
// %n表示换行
System.out.printf("%s%n", "end line");
// 还可以支持多个参数
System.out.printf("%s = %s%n", "Name", "Zhangsan");
// %S将字符串以大写形式输出
System.out.printf("%S = %s%n", "Name", "Zhangsan");


/*** 输出整数类型***/
Integer iObj = 342;
// %d表示将整数格式化为10进制整数
System.out.printf("%d; %d; %d%n", -500, 2343L, iObj);
// %o表示将整数格式化为8进制整数
System.out.printf("%o; %o; %o%n", -500, 2343L, iObj);
// %x表示将整数格式化为16进制整数
System.out.printf("%x; %x; %x%n", -500, 2343L, iObj);
// %X表示将整数格式化为16进制整数,并且字母变成大写形式
System.out.printf("%X; %X; %X%n", -500, 2343L, iObj);

/*** 输出浮点类型***/
Double dObj = 45.6d;
// %f表示以十进制格式化输出浮点数
System.out.printf("%f; %f; %f%n", -756.403f, 7464.232641d, dObj);
// 还可以限制小数点后的位数
System.out.printf("%.1f; %.3f; %f%n", -756.403f, 7464.232641d, dObj);

5.注意点

  • 多组测试数据:

如果出现多组测试数据放在一起的情况,直接在最外层套while(sc.hasNext()),每组测试数据进入一次while循环,运行一次主函数。一直等待输入,除非终止程序。

  • 高精度:

BigInteger和BigDecimal可以说是acmer选择java的首要原因。

函数:add, subtract, divide, mod, compareTo等,其中加减乘除模都要求是BigInteger(BigDecimal)和BigInteger(BigDecimal)之间的运算,所以需要把int(double)类型转换为BigInteger(BigDecimal),用函数BigInteger.valueOf()。

  • 一个非常容易出错的地方:(nextInt转nextLine接收)
假设输入为:
3
a 10 1 2
b 10 2
c 10 3
第一行是是数字n,表示下面有n行输入,下面的n行有字母,也有数字,字母只是标识符,不参与运算,数字的个数不固定,每一行的数字需要用List存储下来,最后将每一行的List放入一个大的List中。

正确代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //需要在后面添加sc.nextLine();换到下一行
        sc.nextLine();
        List<List<Integer>> adj = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            List<Integer> list = new ArrayList<>();
            String[] inputs = sc.nextLine().split(" ");

            for (int j = 1; j < inputs.length; j++) {
                list.add(Integer.valueOf(inputs[j]));
            }
            adj.add(list);
            System.out.println(list);
        }
    }
}

  • 赛码平台注意点:

    • 不要自定义包名称,否则会报错,即不要添加package answer之类的语句;

    • 写很多个类,但是必须有一个类名为Main,并且为public属性,并且Main为唯一的public class;

    • Main类的里面必须包含一个名字为’main’的静态方法(函数),这个方法是程序的入口。

2.数字处理

  • 如果是读取 Long,则使用:in.hasNextLong()Long a = in.nextLong()
  • 读取小数:f = scan.nextFloat()double weight = scan.nextDouble()

1.1多组空格分隔的两个正整数-每组个数相同

(1)输入描述:

输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。

(2)输出描述:

输出a+b的结果

(3)示例
输入:

1 5
10 20

输出:

6
30

代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //注意while 处理多个case
        while (in.hasNext()) {
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a + b);
        }
    }
}

1.2第一行组数接空格分隔的两个正整数-每组个数相同

(1)输入描述:

输入第一行包括一个数据组数t(1 <= t <= 100)
接下来每行包括两个正整数a,b(1 <= a, b <= 1000)

(2)输出描述:

输出a+b的结果

(3)示例
输入:

2
1 5
10 20

输出:

6
30

代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        //遍历循环
        for (int i = 0; i < num; i++) {
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a+b);
        }
    }
}

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        //num从最高到0的循环
        while (num--> 0) {
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a+b);
        }
    }
}

1.3空格分隔的两个正整数为 0 0 结束

(1)输入描述:

输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入

(2)输出描述:

输出a+b的结果

(3)示例
输入:

1 5
10 20
0 0

输出:

6
30

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        List<Integer> list = new ArrayList<Integer>();
        Boolean endFlag = false;
        // 注意 while 处理多个 case
        // 注意 hasNext 和hasNextLine 区别
        while (in.hasNextInt() && !endFlag) {
            int a = in.nextInt();
            int b = in.nextInt();
            if(a == 0 && b == 0) {
                endFlag = true;
            } else {
                list.add(a+b);
            }
            list.forEach(e -> System.out.println(e));
        }
    }
}

1.4多组空格分隔的两个正整数-每组个数不同

(1)输入描述:

输入数据有多组, 每行表示一组输入数据。
每行的第一个整数为整数的个数n(1 <= n <= 100)。
接下来n个正整数, 即需要求和的每个正整数。

(2)输出描述:

每组数据输出求和的结果

(3)示例
输入:

4 1 2 3 4
5 1 2 3 4 5

输出:

14
20

代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //注意while 处理多个case
        while (in.hasNext()) {
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a + b);
        }
    }
}

1.5每行第一个为个数后带空格分割整数为0结束

(1)输入描述:

输入数据包括多组。
每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。
接下来n个正整数,即需要求和的每个正整数。

(2)输出描述:

每组数据输出求和的结果

(3)示例
输入:

4 1 2 3 4
5 1 2 3 4 5
0

输出:

14
20

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        List<Integer> list = new ArrayList<>();
        Boolean endFlag = false;
        while (in.hasNextInt() && !endFlag) {
            int a = in.nextInt();
            if(a != 0) {
                int sum = 0;
                for (int i = 0; i < a; i++) {
                    sum += in.nextInt();
                }
                list.add(sum);
            }else {
                endFlag = true;
            }
        }
        list.forEach(e -> System.out.println(e));

    }
}

1.6第一行组数接空格分隔的两个正整数-每组个数不同

(1)输入描述:

输入数据包括多组。
每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。
接下来n个正整数,即需要求和的每个正整数。

(2)输出描述:

每组数据输出求和的结果

(3)示例
输入:

2
4 1 2 3 4
5 1 2 3 4 5

输出:

14
20

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        for (int i = 0; i < num; i++) {
            int len = in.nextInt();
            int res = 0;
            for (int j = 0; j < len; j++) {
                int a = in.nextInt();
                res += a;
            }
            System.out.println(res);
        }

    }
}

1.7 输入一个数组,且给出了数组的长度

输入:

7
1 2 3 4 5 6 7

输出:

1 2 3 4 5 6 7

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int len = in.nextInt();
        int[] array = new int[len];
        for (int i = 0; i < len; i++) {
            array[i] = in.nextInt();
        }
        System.out.println(Arrays.toString(array));

    }
}

2.字符串处理

比较项next( )nextLine( )
说明只能读取到空格之前的字符串可以读取空格的字符串
比如“你好 java”“你好”“你好 java”
使用前判断in.hasNext()in.hasNextLine()

2.1 第一行个数第二行字符串

输入:

2
a b c
1 2 3

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        in.nextLine();
        while (in.hasNext()){
            String[] s = in.nextLine().split(" ");
            System.out.println(s);
        }

    }
}

2.2多行空格分开的字符串

代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()){
            String[] s = in.nextLine().split(" ");
            System.out.println(s);
        }

    }
}

3.核心模板

import java.util.*; 
public class Main {

    public static void main(String[] args) {
        //1.数据输入
        Scanner in = new Scanner(System.in);
        //读数字
        int numLen = in.nextInt();
        int[] numArr = new int[numLen];
        int i = 0;
        while(in.hasNextInt() && i < numLen){
            numArr[i] = in.nextInt();
            i++;
        }
        //读字符串
        int strLen = in.nextInt();
        //数字到字符串要换行
        in.nextLine(); 
        String[] strArr = new String[strLen];
        //或者 strArr[] = in.nextLine().split(" ");
        int j = 0;
        while(in.hasNextLine() && j < strLen){
            strArr[j] = in.nextLine();
            j++;
        }
        
        //2. 处理
        Solution solution = new Solution();
        String result = solution.process(numArr, strArr);
        
        //3. 输出
        System.out.println(result);
        //四舍五入输出小数
        String str = String.format("%.2f",3.555);
        System.out.println(str);
    }
}

//下面类似 LeetCode 的核心代码模式
class Solution {
    public String process(int[] nums, String[] strs) {
        StringBuilder sb = new StringBuilder();
        sb.append(Arrays.toString(nums));
        sb.append(" && ");
        sb.append(Arrays.toString(strs));
        return sb.toString();
    }
}
  • 15
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1 图论 3 1.1 术语 3 1.2 独立集、覆盖集、支配集之间关系 3 1.3 DFS 4 1.3.1 割顶 6 1.3.2 桥 7 1.3.3 强连通分量 7 1.4 最小点基 7 1.5 拓扑排序 7 1.6 欧拉路 8 1.7 哈密顿路(正确?) 9 1.8 Bellman-ford 9 1.9 差分约束系统(用bellman-ford解) 10 1.10 dag最短路径 10 1.11 二分图匹配 11 1.11.1 匈牙利算法 11 1.11.2 KM算法 12 1.12 网络流 15 1.12.1 最大流 15 1.12.2 上下界的网络的最大流 17 1.12.3 上下界的网络的最小流 17 1.12.4 最小费用最大流 18 1.12.5 上下界的网络的最小费用最小流 21 2 数论 21 2.1 最大公约数gcd 21 2.2 最小公倍数lcm 22 2.3 快速幂取模B^LmodP(O(logb)) 22 2.4 Fermat小定理 22 2.5 Rabin-Miller伪素数测试 22 2.6 Pollard-rho 22 2.7 扩展欧几里德算法extended-gcd 24 2.8 欧拉定理 24 2.9 线性同余方程ax≡b(mod n) 24 2.10 中国剩余定理 25 2.11 Discrete Logging(BL == N (mod P)) 26 2.12 N!最后一个不为0的数字 27 2.13 2^14以内的素数 27 3 数据结构 31 3.1 堆(最小堆) 31 3.1.1 删除最小值元素: 31 3.1.2 插入元素和向上调整: 32 3.1.3 堆的建立 32 3.2 并查集 32 3.3 树状数组 33 3.3.1 LOWBIT 33 3.3.2 修改a[p] 33 3.3.3 前缀和A[1]+…+A[p] 34 3.3.4 一个二维树状数组的程序 34 3.4 线段树 35 3.5 字符串 38 3.5.1 字符串哈希 38 3.5.2 KMP算法 40 4 计算几何 41 4.1 直线交点 41 4.2 判断线段相交 41 4.3 三点外接圆圆心 42 4.4 判断点在多边形内 43 4.5 两圆交面积 43 4.6 最小包围圆 44 4.7 经纬度坐标 46 4.8 凸包 46 5 Problem 48 5.1 RMQ-LCA 48 5.1.1 Range Minimum Query(RMQ) 49 5.1.2 Lowest Common Ancestor (LCA) 53 5.1.3 Reduction from LCA to RMQ 56 5.1.4 From RMQ to LCA 57 5.1.5 An algorithm for the restricted RMQ 60 5.1.6 An AC programme 61 5.2 最长公共子序列LCS 64 5.3 最长上升子序列/最长不下降子序列(LIS) 65 5.3.1 O(n^2) 65 5.3.2 O(nlogn) 66 5.4 Joseph问题 67 5.5 0/1背包问题 68 6 组合数学相关 69 6.1 The Number of the Same BST 69 6.2 排列生成 71 6.3 逆序 72 6.3.1 归并排序求逆序 72 7 数值分析 72 7.1 二分法 72 7.2 迭代法(x=f(x)) 73 7.3 牛顿迭代 74 7.4 数值积分 74 7.5 高斯消元 75 8 其它 77

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值