【经验总结】Java在ACM算法竞赛编程中易错点
一、Java之ACM易错点
1. 类名称必须采用public class Main方式命名
2. 在有些OJ系统上,即便是输出的末尾多了一个“ ”,程序可能会输出错误,所以在我看来好多OJ系统做的是非常之垃圾
3. 有些OJ上的题目会直接将OI上的题目拷贝过来,所以即便是题目中有输入和输出文件,可能也不需要,因为在OJ系统中一般是采用标准输入输出,不需要文件
4. 在有多行数据输入的情况下,一般这样处理:
static Scanner in = new Scanner(System.in);
while(in.hasNextInt())
或者是
while(in.hasNext())
5. 有关System.nanoTime()函数的使用,该函数用来返回最准确的可用系统计时器的当前值,以毫微秒为单位。
- long startTime = System.nanoTime();
- // ... the code being measured ...
- long estimatedTime = System.nanoTime() - startTime;
二、Java之输入输出处理
由于ACM竞赛题目的输入数据和输出数据一般有多组(不定),并且格式多种多样,所以,如何处理题目的输入输出是对大家的一项最基本的要求。这也是困扰初学者的一大问题。
1. 输入:
格式1:Scanner sc = new Scanner (new BufferedInputStream(System.in));
格式2:Scanner sc = new Scanner (System.in);
在读入数据量大的情况下,格式1的速度会快些。
读一个整数: int n = sc.nextInt(); 相当于 scanf("%d", &n); 或 cin >> n;
读一个字符串:String s = sc.next(); 相当于 scanf("%s", s); 或 cin >> s;
读一个浮点数:double t = sc.nextDouble(); 相当于 scanf("%lf", &t); 或 cin >> t;
读一整行: String s = sc.nextLine(); 相当于 gets(s); 或 cin.getline(...);
判断是否有下一个输入可以用sc.hasNext()或sc.hasNextInt()或sc.hasNextDouble()或sc.hasNextLine()
例1:读入整数
- Input 输入数据有多组,每组占一行,由一个整数组成。
- Sample Input
- 56
- 67
- 100
- 123
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc =new Scanner(System.in);
- while(sc.hasNext()){ //判断是否结束
- int score = sc.nextInt();//读入整数
- 。。。。
- }
- }
- }
例2:读入实数
输入数据有多组,每组占2行,第一行为一个整数N,指示第二行包含N个实数。
- Sample Input
- 4
- 56.9 67.7 90.5 12.8
- 5
- 56.9 67.7 90.5 12.8
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc =new Scanner(System.in);
- while(sc.hasNext()){
- int n = sc.nextInt();
- for(int i=0;i<n;i++){
- double a = sc.nextDouble();
- 。。。。。。
- }
- }
- }
- }
例3:读入字符串【杭电2017 字符串统计】
输入数据有多行,第一行是一个整数n,表示测试实例的个数,后面跟着n行,每行包括一个由字母和数字组成的字符串。
- Sample Input
- 2
- asdfasdf123123asdfasdf
- asdf111111111asdfasdfasdf
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- int n = sc.nextInt();
- for(int i=0;i<n;i++){
- String str = sc.next();
- ......
- }
- }
- }
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- int n = Integer.parseInt(sc.nextLine());
- for(int i=0;i<n;i++){
- String str = sc.nextLine();
- ......
- }
- }
- }
例3:读入字符串【杭电2005 第几天?】
- 给定一个日期,输出这个日期是该年的第几天。
- Input 输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成
- 1985/1/20
- 2006/3/12
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- int[] dd = {0,31,28,31,30,31,30,31,31,30,31,30,31};
- while(sc.hasNext()){
- int days = 0;
- String str = sc.nextLine();
- String[] date = str.split("/");
- int y = Integer.parseInt(date[0]);
- int m = Integer.parseInt(date[1]);
- int d = Integer.parseInt(date[2]);
- if((y%400 == 0 || (y%4 == 0 && y%100 !=0)) && m>2) days ++;
- days += d;
- for(int i=0;i<m;i++){
- days += dd[i];
- }
- System.out.println(days);
- }
- }
- }
2. 输出
函数:
System.out.print();
System.out.println();
System.out.format();
System.out.printf();
例4 杭电1170Balloon Comes!
Give you an operator (+,-,*, / --denoting addition, subtraction, multiplication, division respectively) and two positive integers, your task is to output the result.
Input
Input contains multiple test cases. The first line of the input is a single integer T (0<T<1000) which is the number of test cases. T test cases follow. Each test case contains a char C (+,-,*, /) and two integers A and B(0<A,B<10000).Of course, we all know that A and B are operands and C is an operator.
Output
For each case, print the operation result. The result should be rounded to 2 decimal places If and only if it is not an integer.
Sample Input
4
+ 1 2
- 1 2
* 1 2
/ 1 2
Sample Output
3
-1
2
0.50
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner sc =new Scanner(System.in);
- int n = sc.nextInt();
- for(int i=0;i<n;i++){
- String op = sc.next();
- int a = sc.nextInt();
- int b = sc.nextInt();
- if(op.charAt(0)=='+'){
- System.out.println(a+b);
- }else if(op.charAt(0)=='-'){
- System.out.println(a-b);
- }else if(op.charAt(0)=='*'){
- System.out.println(a*b);
- }else if(op.charAt(0)=='/'){
- if(a % b == 0) System.out.println(a / b);
- else System.out.format("%.2f", (a / (1.0*b))). Println();
- }
- }
- }
- }
3. 规格化的输出:
函数:
// 这里0指一位数字,#指除0以外的数字(如果是0,则不显示),四舍五入.
DecimalFormat fd = new DecimalFormat("#.00#");
DecimalFormat gd = new DecimalFormat("0.000");
System.out.println("x =" + fd.format(x));
System.out.println("x =" + gd.format(x));
- public static void main(String[] args) {
- NumberFormat formatter = new DecimalFormat( "000000");
- String s = formatter.format(-1234.567); // -001235
- System.out.println(s);
- formatter = new DecimalFormat( "##");
- s = formatter.format(-1234.567); // -1235
- System.out.println(s);
- s = formatter.format(0); // 0
- System.out.println(s);
- formatter = new DecimalFormat( "##00");
- s = formatter.format(0); // 00
- System.out.println(s);
- formatter = new DecimalFormat( ".00");
- s = formatter.format(-.567); // -.57
- System.out.println(s);
- formatter = new DecimalFormat( "0.00");
- s = formatter.format(-.567); // -0.57
- System.out.println(s);
- formatter = new DecimalFormat( "#.#");
- s = formatter.format(-1234.567); // -1234.6
- System.out.println(s);
- formatter = new DecimalFormat( "#.######");
- s = formatter.format(-1234.567); // -1234.567
- System.out.println(s);
- formatter = new DecimalFormat( ".######");
- s = formatter.format(-1234.567); // -1234.567
- System.out.println(s);
- formatter = new DecimalFormat( "#.000000");
- s = formatter.format(-1234.567); // -1234.567000
- System.out.println(s);
- formatter = new DecimalFormat( "#,###,###");
- s = formatter.format(-1234.567); // -1,235
- System.out.println(s);
- s = formatter.format(-1234567.890); // -1,234,568
- System.out.println(s);
- // The ; symbol is used to specify an alternate pattern for negative values
- formatter = new DecimalFormat( "#;(#) ");
- s = formatter.format(-1234.567); // (1235)
- System.out.println(s);
- // The ' symbol is used to quote literal symbols
- formatter = new DecimalFormat( " '# '# ");
- s = formatter.format(-1234.567); // -#1235
- System.out.println(s);
- formatter = new DecimalFormat( " 'abc '# ");
- s = formatter.format(-1234.567); // - abc 1235
- System.out.println(s);
- formatter = new DecimalFormat( "#.##%");
- s = formatter.format(-12.5678987);
- System.out.println(s);
- }
4. 字符串处理 String
String 类用来存储字符串,可以用charAt方法来取出其中某一字节,计数从0开始:
String a = "Hello"; // a.charAt(1) = 'e'
用substring方法可得到子串,如上例
System.out.println(a.substring(0, 4)) // output "Hell"
注意第2个参数位置上的字符不包括进来。这样做使得 s.substring(a, b) 总是有 b-a个字符。
字符串连接可以直接用 + 号,如
String a = "Hello";
String b = "world";
System.out.println(a + ", " + b + "!"); // output "Hello, world!"
如想直接将字符串中的某字节改变,可以使用另外的StringBuffer类。
- import java.io.BufferedInputStream;
- import java.math.BigInteger;
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Scanner cin = new Scanner (new BufferedInputStream(System.in));
- int a = 123, b = 456, c = 7890;
- BigInteger x, y, z, ans;
- x = BigInteger.valueOf(a);
- y = BigInteger.valueOf(b);
- z = BigInteger.valueOf(c);
- ans = x.add(y); System.out.println(ans);
- ans = z.divide(y); System.out.println(ans);
- ans = x.mod(z); System.out.println(ans);
- if (ans.compareTo(x) == 0) System.out.println("1");
- }
- }
6. 进制转换
String st = Integer.toString(num, base); // 把num当做10进制的数转成base进制的st(base <= 35).
int num = Integer.parseInt(st, base); // 把st当做base进制,转成10进制的int(parseInt有两个参数,第一个为要转的字符串,第二个为说明是什么进制).
BigInter m = new BigInteger(st, base); // st是字符串,base是st的进制.
7. 数组排序
函数:Arrays.sort();
5. 高精度
BigInteger和BigDecimal可以说是acmer选择java的首要原因。
函数:add, subtract, divide, mod, compareTo等,其中加减乘除模都要求是BigInteger(BigDecimal)和BigInteger(BigDecimal)之间的运算,所以需要把int(double)类型转换为BigInteger(BigDecimal),用函数BigInteger.valueOf().
- public class Main {
- public static void main(String[] args) {
- Scanner cin = new Scanner (new BufferedInputStream(System.in));
- int n = cin.nextInt();
- int a[] = new int [n];
- for (int i = 0; i < n; i++) a[i] = cin.nextInt();
- Arrays.sort(a);
- for (int i = 0; i < n; i++) System.out.print(a[i] + " ");
- }
- }
易错:
1.for(int i=m;i<n;i++){isFlowerNum(m);} //这里m是不变量,应该用i
2.m=m/10的值就变化了如果想要继续用m,应该提前保存
一、Java之ACM注意点
1. 类名称必须采用public class Main方式命名
2. 在有些OJ系统上,即便是输出的末尾多了一个“ ”,程序可能会输出错误,所以在我看来好多OJ系统做的是非常之垃圾
3. 有些OJ上的题目会直接将OI上的题目拷贝过来,所以即便是题目中有输入和输出文件,可能也不需要,因为在OJ系统中一般是采用标准输入输出,不需要文件
4. 在有多行数据输入的情况下,一般这样处理,
- static Scanner in = new Scanner(System.in);
- while(in.hasNextInt())
- 或者是
- while(in.hasNext())
5. 有关System.nanoTime()函数的使用,该函数用来返回最准确的可用系统计时器的当前值,以毫微秒为单位。
- long startTime = System.nanoTime();
- // ... the code being measured ...
- long estimatedTime = System.nanoTime() - startTime;
二、Java之输入输出处理
由于ACM竞赛题目的输入数据和输出数据一般有多组(不定),并且格式多种多样,所以,如何处理题目的输入输出是对大家的一项最基本的要求。这也是困扰初学者的一大问题。
1. 输入:
格式1:Scanner sc = new Scanner (new BufferedInputStream(System.in));
格式2:Scanner sc = new Scanner (System.in);
在读入数据量大的情况下,格式1的速度会快些。
读一个整数: int n = sc.nextInt(); 相当于 scanf("%d", &n); 或 cin >> n;
读一个字符串:String s = sc.next(); 相当于 scanf("%s", s); 或 cin >> s;
读一个浮点数:double t = sc.nextDouble(); 相当于 scanf("%lf", &t); 或 cin >> t;
读一整行: String s = sc.nextLine(); 相当于 gets(s); 或 cin.getline(...);
判断是否有下一个输入可以用sc.hasNext()或sc.hasNextInt()或sc.hasNextDouble()或sc.hasNextLine()
例1:读入整数
|
例2:读入实数
输入数据有多组,每组占2行,第一行为一个整数N,指示第二行包含N个实数。
|
例3:读入字符串【杭电2017 字符串统计】
输入数据有多行,第一行是一个整数n,表示测试实例的个数,后面跟着n行,每行包括一个由字母和数字组成的字符串。
|
例3:读入字符串【杭电2005 第几天?】
|
2. 输出
函数:
System.out.print();
System.out.println();
System.out.format();
System.out.printf();
例4 杭电1170Balloon Comes!
Give you an operator (+,-,*, / --denoting addition, subtraction, multiplication, division respectively) and two positive integers, your task is to output the result.
Input
Input contains multiple test cases. The first line of the input is a single integer T (0<T<1000) which is the number of test cases. T test cases follow. Each test case contains a char C (+,-,*, /) and two integers A and B(0<A,B<10000).Of course, we all know that A and B are operands and C is an operator.
Output
For each case, print the operation result. The result should be rounded to 2 decimal places If and only if it is not an integer.
Sample Input
4
+ 1 2
- 1 2
* 1 2
/ 1 2
Sample Output
3
-1
2
0.50
|
3. 规格化的输出:
函数:
// 这里0指一位数字,#指除0以外的数字(如果是0,则不显示),四舍五入.
DecimalFormat fd = new DecimalFormat("#.00#");
DecimalFormat gd = new DecimalFormat("0.000");
System.out.println("x =" + fd.format(x));
System.out.println("x =" + gd.format(x));
|
4. 字符串处理 String
String 类用来存储字符串,可以用charAt方法来取出其中某一字节,计数从0开始:
String a = "Hello"; // a.charAt(1) = 'e'
用substring方法可得到子串,如上例
System.out.println(a.substring(0, 4)) // output "Hell"
注意第2个参数位置上的字符不包括进来。这样做使得 s.substring(a, b) 总是有 b-a个字符。
字符串连接可以直接用 + 号,如
String a = "Hello";
String b = "world";
System.out.println(a + ", " + b + "!"); // output "Hello, world!"
如想直接将字符串中的某字节改变,可以使用另外的StringBuffer类。
5. 高精度
BigInteger和BigDecimal可以说是acmer选择java的首要原因。
函数:add, subtract, divide, mod, compareTo等,其中加减乘除模都要求是BigInteger(BigDecimal)和BigInteger(BigDecimal)之间的运算,所以需要把int(double)类型转换为BigInteger(BigDecimal),用函数BigInteger.valueOf().
|
6. 进制转换
String st = Integer.toString(num, base); // 把num当做10进制的数转成base进制的st(base <= 35).
int num = Integer.parseInt(st, base); // 把st当做base进制,转成10进制的int(parseInt有两个参数,第一个为要转的字符串,第二个为说明是什么进制).
BigInter m = new BigInteger(st, base); // st是字符串,base是st的进制.
7. 数组排序
函数:Arrays.sort();
|
易错:
1.for(int i=m;i<n;i++){isFlowerNum(m);} //这里m是不变量,应该用i
2.m=m/10的值就变化了如果想要继续用m,应该提前保存
【经验总结】Java在ACM算法竞赛编程中易错点的更多相关文章
- 编程中易犯错误汇总:一个综合案例.md
# 11编程中易犯错误汇总:一个综合案例 在上一篇文章中,我们学习了如何区分好的代码与坏的代码,如何写好代码.所谓光说不练假把式,在这篇文章中,我们就做一件事——一起来写代码.首先,我会先列出问题,然 ...
- ACM算法竞赛:抄课文
题目如下: 比如现在要写一句话 Hello world 输入: n (n > 0) 比如输入的n为10,就将Hello world打印十 #include <stdio.h> #in ...
- Java加密AES算法及spring中应用
开门见山直接贴上代码 .AESUtil加密解密工具类 import java.security.Key; import java.security.SecureRandom; import java. ...
- 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结
概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...
- Java基础篇Socket网络编程中的应用实例
说到java网络通讯章节的内容,刚入门的学员可能会感到比较头疼,应为Socket通信中一定会伴随有IO流的操作,当然对IO流比较熟练的哥们会觉得这是比较好玩的一章,因为一切都在他们的掌握之中,这样操作 ...
- ACM -- 算法小结(二)错排公式的应用
pala提出的问题: 十本不同的书放在书架上.现重新摆放,使每本书都不在原来放的位置.有几种摆法? 这个问题推广一下,就是错排问题: n个有序的元素应有n!种不同的排列.如若一个排列式的所有的元素都 ...
- java中易错点(二)
java,exe是java虚拟机 javadoc.exe用来制作java文档 jdb.exe是java的调试器 javaprof,exe是剖析工具 解析一: sleep是线程类(Thread)的方法, ...
- java中易错点(一)
由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/".如果想替换的只是&qu ...
- java中易错点
1.A instanceof B{这是没有好好利用java多态的表现} java中的二元操作符,测试A对象是否是B类的实例: 返回值:boolean类型 2.“==”与 “equals”的区别: = ...
随机推荐
- getchar() 、 scanf() 、流与缓冲区
C中的缓冲区一直是debug的重灾区,今天在写一个命令行界面的时候又遇到了这个问题,所以来总结一波. 两函数的不同之处 scanf() 会把 stdinBuff 中的特定格式数据取出,非特定格式数据则 ...
- Say Hello to ConstraintLayout
ConstraintLayout介绍 ConstraintLayout让你可以在很平的view结构(没有多层布局嵌套)中构建一个复杂的布局结构. 有点像RelativeLayout, 所有的view都 ...
- php项目报错 Warning: session_start(): open(D:/software/wamp/wamp/tmp\sess_msrjot7f32ciqb1p2hr4ahejg4, O_RDWR) f
今天一个php项目报错: Warning: session_start(): open(D:/software/wamp/wamp/tmp\sess_msrjot7f32ciqb1p2hr4ahejg ...
- bzoj 4237: 稻草人
Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要 ...
- New Life With 2018
2017年转眼过去了.对自己来说.这一大年是迷茫和认知的一年.我的第一篇博客就这样记录下自己的历程吧 一:选择 从进入这一行到现在已经一年多了,2016年11月份就像所有的应届毕业生一样,都贼反感毕业 ...
- package-cleanup
package-cleanup 是一个python开发的命令程序,用来清除本机已安装的.重复的 或孤立的软件包. desktop版的CentOS镜像包含这个工具,而Minimal版的CentOS镜像不 ...
- Web框架django[Form]组件
新手上路 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1.创建Form类 # 创 ...
- Node.js 蚕食计划(一)—— 模块化编程
众所周知,Node.js 的出现造就了全栈工程师,因为它让 JavaScript 的舞台从浏览器扩大到了服务端 而 Node.js 的强大也得益于它庞大的模块库,所以学习 Node.js 第一步还得从 ...
- MySQL ALTER TABLE: ALTER vs CHANGE vs MODIFY COLUMN
ALTER COLUMN 语法: ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} 作用: 设置或删除列的默认值.该操作会直接修 ...
- ping、traceroute原理
说明:忘记从哪里拉的博文了,感谢! ping 用类型码为0的ICMP发请 求,受到请求的主机则用类型码为8的ICMP回应. ping程序来计算间隔时间,并计算有多少个包被送达.用户就可以判断网络大致的 ...