第1章 变量、运算符、表达式、输入与输出
笔记
OJ中要求主类必须是public class Main
变量
变量必须先定义,才可以使用,而且不能(在同一个代码块)重名。
变量定义的方式:
public class Main {
public static void main(String[] args) {
int a = 5;
int b, c = a, d = 10 / 2;
}
}
内置数据类型
类型 | 字节数 | 举例 |
---|---|---|
byte |
1 | 123 |
short |
2 | 12345 |
int |
4 | 123456789 |
long |
8 | 1234567891011L |
float |
4 | 1.2F |
double |
8 | 1.2 ,1.2D |
boolean |
8 | true ,false |
char |
2 | 'A' |
常量
使用final
修饰:
final int N = 110;
类型转化
范围小的类型会自动转换为范围大的范围,例如int
会自动转成long
。范围大的类型不会自动转换,需要显示转化。
int x = (int) 'A'; // 显示转化
double x = 12, y = 4 * 3.3; // 隐式转化
运算符
a = 10; // 赋值运算符
b = 10; // 赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
+ |
把两个数相加 | a + b 将得到30 |
- |
从第一个数中减去第二个数 | a - b 将得到-10 |
* |
把两个数相乘 | a * b 将得到 200 |
/ |
分子除以分母 | b / a 将得到2 |
% |
取模运算符,向零整除后的余数,注意余数可能为负数 | b % a 将得到 0 |
++ |
自增运算符 | a++ :先取值后加1;++a :先加1后取值 |
-- |
自减运算符 | a-- :先取值后减1;--a :先减1后取值 |
+= |
第一个数加上第二个数 | a = a + b 可以简写为 a += b |
-= |
第一个数减去第二个数 | a = a - b 可以简写为 a -= b |
*= |
第一个数乘以第二个数 | a = a * b 可以简写为 a *= b |
/= |
第一个数除以第二个数 | a = a / b 可以简写为 a /= b |
%= |
第一个对第二个数取余数 | a = a % b 可以简写为 a %= b |
Java和C++都是向下取整,因此-2.5
取整后得-3
;而python是向零取整,因此-2.5
取整后得-2
。
在数学中$-30 \mod{20}=10$,余数一定是正数,但在Java中,-30 % 20 = -10
,余数的符号与被除数一致。
例
public class Main {
public static void main(String[] args) {
double x = 1.5, y = 3.2;
System.out.println(x * y); // 4.80000000000001
System.out.println(x + y); // 4.7
System.out.println(x - y); // -1.7000000000000002
System.out.println(x / y); // 0.46875
}
}
可以发现乘法和减法的计算结果出现误差,在精度要求不高的时候,可以忽略此问题。在比较浮点数时,用绝对值比较,例如Math.abs(x - y) < 1e-8
输入
方式1:Scanner
效率较低,输入规模较小($10^5$以内)时使用。
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
String str = scanner.next(); // 读入下一个字符串
int x = scanner.nextInt(); // 读入下一个整数
float y = scanner.nextFloat(); // 读入下一个单精度浮点数
double z = scanner.nextDouble(); // 读入下一个双精度浮点数
String line = scanner.nextLine(); // 读入下一行
scanner.close();
}
}
方式2:BufferedReader
效率较高,输入规模较大($10^5$以上)时使用。注意需要在main
方法中声明方法会抛出异常throws Exception
。
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String str = bufferedReader.readLine();
int x = Integer.parseInt(str); // 手动转成整数类型
String[] strs = bufferedReader.readLine().split(" "); // 同一行多个输入
System.out.println(x);
bufferedReader.close();
}
}
输出
方式1:println
和printf
效率较低,输出规模较小($10^5$以内)时使用。
print
与println
的区别在于前者输出后不会换行,后者会。
printf
与print
的区别在于,前者需要指名输出格式,用于格式化输出字符串,与C++中的printf
一样;而后者是直接按原始类型输出。
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(123); // 输出整数 + 换行
System.out.println("Hello World"); // 输出字符串 + 换行
System.out.print(123); // 输出整数
System.out.print("yxc\n"); // 输出字符串
System.out.printf("%04d %.2f\n", 4, 123.456D); // 格式化输出,float与double都用%f输出
}
}
%04d
表示输出整数,占据4个空格的位置,空白处自动补0。
%.2f
表示输出浮点数,保留2位小数。
System.out.printf()
中不同类型变量的输出格式:
(1) int
:%d
(2) float
: %f
, 默认保留6位小数
(3) double
: %f
, 默认保留6位小数
(4) char
: %c
, 回车也是一个字符,用’\n’表示
(5) String
: %s
方式2:BufferedWriter
效率较高,输出规模较大($10^5$以上)时使用。注意需要抛异常。
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
bufferedWriter.write("Hello World\n");
bufferedWriter.flush(); // 需要手动刷新缓冲区
bufferedWriter.close();
}
}
习题
AcWing 1. A + B
方法1:Scanner
和println
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println(a + b);
scanner.close();
}
}
方法2:BufferedReader
和BufferedWriter
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] strs = bufferedReader.readLine().split(" ");
int a = Integer.parseInt(strs[0]);
int b = Integer.parseInt(strs[1]);
bufferedReader.close();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
bufferedWriter.write(String.valueOf(a + b));
bufferedWriter.flush();
bufferedWriter.close();
}
}
AcWing 608. 差
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt(), b = scanner.nextInt();
int c = scanner.nextInt(), d = scanner.nextInt();
scanner.close();
System.out.printf("DIFERENCA = %d\n", a * b - c * d);
}
}
AcWing 604. 圆的面积
import java.util.Scanner;
public class Main {
public static final double PI = 3.14159;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double r = scanner.nextDouble();
double area = r * r * PI;
System.out.printf("A=%.4f\n", area);
scanner.close();
}
}
注意本题指明了PI = 3.14159
,因此不能通过import static java.lang.Math.PI
获取PI
。
AcWing 606. 平均数1
import java.util.Scanner;
public class Main {
public static final double[] COEF = {3.5, 7.5};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double a = scanner.nextDouble(), b = scanner.nextDouble();
double average = (COEF[0] * a + COEF[1] * b) / (COEF[0] + COEF[1]);
System.out.printf("MEDIA = %.5f\n", average);
scanner.close();
}
}
AcWing 609. 工资
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int number = scanner.nextInt(), n = scanner.nextInt();
double salary = scanner.nextDouble();
System.out.println("NUMBER = " + number);
System.out.printf("SALARY = U$ %.2f\n", n * salary);
scanner.close();
}
}
AcWing 615. 油耗
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int total = scanner.nextInt();
double volumn = scanner.nextDouble();
System.out.printf("%.3f km/l\n", total / volumn);
scanner.close();
}
}
AcWing 616. 两点间的距离
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double x1 = scanner.nextDouble(), y1 = scanner.nextDouble();
double x2 = scanner.nextDouble(), y2 = scanner.nextDouble();
double dx = x1 - x2, dy = y1 - y2;
double distance = Math.sqrt(dx * dx + dy * dy);
System.out.printf("%.4f\n", distance);
scanner.close();
}
}
AcWing 653. 钞票
import java.util.Scanner;
public class Main {
public static int[] a = {100, 50, 20, 10, 5, 2, 1};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
System.out.println(m);
for(int i = 0; i < a.length; i++) {
int nota = a[i];
System.out.printf("%d nota(s) de R$ %d,00\n", m / nota, nota);
m -= (m / nota) * nota;
}
scanner.close();
}
}
笔记
- 贪心策略:从最大面值的钞票开始考虑,每次用最多且不超过当前需要金额的钞票数,直至考虑到最小面值的钞票(类似实际中找钱的策略)
- 基于贪心策略的方法能保证“所用的钞票数量尽可能少”,可用交换法反证其合理性
- 可用数组优化编写代码的过程:在数组中按降序存储不同钞票的面值
AcWing 654. 时间转换
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.close();
int hour = n / 3600, minute = (n - hour * 3600) / 60, second = n % 60;
System.out.println(hour + ":" + minute + ":" + second);
}
}
AcWing 605. 简单乘积
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt(), b = scanner.nextInt();
scanner.close();
System.out.println("PROD = " + (a * b));
}
}
AcWing 611. 简单计算
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int id1 = scanner.nextInt(), n1 = scanner.nextInt();
double price1 = scanner.nextDouble();
int id2 = scanner.nextInt(), n2 = scanner.nextInt();
double price2 = scanner.nextDouble();
scanner.close();
System.out.printf("VALOR A PAGAR: R$ %.2f\n", n1 * price1 + n2 * price2);
}
}
AcWing 612. 球的体积
import java.util.Scanner;
public class Main {
public static final double PI = 3.14159;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double r = scanner.nextDouble();
scanner.close();
double volumn = 4.0 * PI * r * r * r / 3;
System.out.printf("VOLUME = %.3f\n", volumn);
}
}
AcWing 613. 面积
import java.util.Scanner;
public class Main {
public static final double PI = 3.14159;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double a = scanner.nextDouble();
double b = scanner.nextDouble();
double c = scanner.nextDouble();
scanner.close();
System.out.printf("TRIANGULO: %.3f\n", a * c / 2.0);
System.out.printf("CIRCULO: %.3f\n", PI * c * c);
System.out.printf("TRAPEZIO: %.3f\n", (a + b) * c / 2.0);
System.out.printf("QUADRADO: %.3f\n", b * b);
System.out.printf("RETANGULO: %.3f\n", a * b);
}
}
AcWing 607. 平均数2
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();
scanner.close();
System.out.printf("MEDIA = %.1f\n", (2 * a + 3 * b + 5 * c) / 10.0);
}
}
AcWing 610. 工资和奖金
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
double base = scanner.nextDouble();
double money = scanner.nextDouble();
scanner.close();
System.out.printf("TOTAL = R$ %.2f\n", base + 0.15 * money);
}
}
AcWing 614. 最大值
import java.util.Scanner;
public class Main {
public static int myMax(int a, int b) {
return (int)(a + b + Math.abs(a - b)) / 2;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
scanner.close();
System.out.printf("%d eh o maior\n", myMax(myMax(a, b), c));
}
}
AcWing 617. 距离
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int distance = scanner.nextInt();
scanner.close();
System.out.printf("%d minutos\n", distance * 2);
}
}
AcWing 618. 燃料消耗
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt(), v = scanner.nextInt();
scanner.close();
System.out.printf("%.3f\n", (double)t * v / 12.0);
}
}
笔记
计算油耗时,不能用t * v / 12.0
,因为t
和v
都是int
类型,计算乘积后可能会超出int
范围,因此需要先把它们转成double
类型,保证乘积计算正确才行。
AcWing 656. 钞票和硬币
import java.util.Scanner;
public class Main {
public static final int[] BILLS = {10000, 5000, 2000, 1000, 500, 200};
public static final int[] COINS = {100, 50, 25, 10, 5, 1};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = (int)(scanner.nextDouble() * 100);
scanner.close();
System.out.println("NOTAS:");
for (int i = 0; i < BILLS.length; i++) {
System.out.printf("%d nota(s) de R$ %.2f\n", m / BILLS[i], BILLS[i] / 100.0);
m %= BILLS[i];
}
System.out.println("MOEDAS:");
for (int i = 0; i < COINS.length; i++) {
System.out.printf("%d moeda(s) de R$ %.2f\n", m / COINS[i], COINS[i] / 100.0);
m %= COINS[i];
}
}
}
笔记
浮点数表示的金额$\times100$转成整数后,就能避免浮点数不精确的问题。
AcWing 655. 天数转换
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
scanner.close();
int year = m / 365;
m %= 365;
int month = m / 30;
m %= 30;
int day = m;
System.out.println(year + " ano(s)");
System.out.println(month + " mes(es)");
System.out.println(day + " dia(s)");
}
}