输入输出练习网站:https://kamacoder.com/
Java读写模板
Scanner
方式一:Scanner
(效率不高)
public class Main {
public static void main(String[] args) {
// 第一个方式Scanner
Scanner sc = new Scanner(System.in);
String s = sc.next(); // 以空格为分割读取一个字符串
String s1 = sc.nextLine(); // 读取一行数据
int a = sc.nextInt(); // 读取一个整数
}
}
next()
读取结果为String类型,返回String类型。结束标记: 空格, tab键, 回车。
nextInt()
读取结果为一个int类型数据,返回int值。结束标记: 空格, tab键, 回车。
nextLine()
读取结果为String类型,返回String类型。结束标记: 回车。
BufferedReader(推荐使用)
方式二:BufferedReader
(推荐使用)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws IOException {
// 第一个方式BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String str = br.readLine(); // 一次读取一行
// 例如一行输入两个数字a1\a2,用split分割后分别转
String[] arr = str.split(" ");
int a1 = Integer.valueOf(arr[0]);
int a2 = Integer.valueOf(arr[1]);
// 使用out.println() 输出
// 使用out.printf("%.2f", num) 保留两位小数,注意不会换行
// 最后记得flush,不然会没有输出
out.flush();
}
}
StringTokenizer
方式三:StringTokenizer
包装BufferedReader
public class Main {
public static void main(String[] args) throws IOException {
// 第一个方式BufferedReader
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in));)
st.nextToken(); // 移动到下一个token
int i = st.nval; // 读取一个整型数 (因为st.nval是double类型,向下转型需要强转)
st.nextToken();
String str = st.sval; // 读取一个字符串
}
}
参考:【如何用java打acm】https://zhuanlan.zhihu.com/p/476468424
其实在c++和java中,主要的差距就是java的输入输出过于缓慢,读1e6的数据,java的Scanner类可能会需要3s才能读完,System.out.print可能要3s才能写完,所以便有了快读这个说法,快读可以将Java的读写速度缩短至原有基础的1/10 ,接下来我会提供四种方法,核心在第二种和第三种方法,本人推荐第三种 ,第四种也是比较快的,代码也少,推荐指数比第三种小一丢丢
**第三种方法:**StringTokenizer(与上面的方式相同)
快读:FastReader 类
快写:PrintWriter 类,其定义后使用和System.out 用法一样,但是你不需要从System这个类中输出.
以下是P1000 A+B 一题的示例代码
import java.io.*;
import java.util.StringTokenizer;
public class Main { // 注意类名必须为Main
public static void main(String[] args) {
FastReader in = new FastReader();
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
int a = in.nextInt(); // 读取一个int数
String[] dur = in.nextLine().split(" "); // 读取整行数据,用空格分割
//输出:out.println();
// 最后记得flush,不然会没有输出
out.flush();
}
}
// 下面是快读模板。需要使用时直接贴在下面就好了
class FastReader{
StringTokenizer st;
BufferedReader br;
public FastReader(){
br=new BufferedReader(new InputStreamReader(System.in));
}
String next(){
while (st==null||!st.hasMoreElements()){
try {
st=new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
第四种方法: BufferedReader
因为要对br.readLine()做特殊处理,所以和第一种隔开了
import java.io.*;
import java.io.PrintWriter;
class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String line=br.readLine();
out.flush();
}
}
/** 第一种
class Main{
public static void main(String[] args) {
Scanner in=new Scanner(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(System.out);
out.flush();
}
}
*/
非常少,也是比较快的,如果不想记第三种,记第四种也没关系。第三种在一些题目中可以和不关同步流的c++持平。
这里统一对第二种第三种的快读做一个解释
1.只要你定义了PrintWriter#out
作为输出类,那么请你务必在main函数的最后加入out.flush()
函数清除缓冲区,不然控制台可能会没有输出
2.PrintWriter#out
定义后使用和System#out
用法一样,但是你不需要从System这个类中输出,
3.请不要在写了快读的时候再使用其他的输入输出,不然流会乱,同时建议不要使用out.write()
方法,因为他里面接收的参数必须是一个字符串,否则输出会乱码
基本数据结构
链表
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
二叉树
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
使用拓展
1、输入包括多个测试实例,每个测试实例包括…
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
....
}
out.flush();
}
}
2、String
字符串如 "5 2 4 1 7 5"
,转为 int[]
数组
String str = "5 2 4 1 7 5";
String[] strs = str.split(" ");
// 朴素写法
int[] nums = new int[strs.length];
for (int i = 0; i < strs.length; i++) {
nums[i] = Integer.parseInt(strs[i]);
}
// stream流
int[] nums = Arrays.stream(str.split(" "))
.mapToInt(Integer::parseInt)
.toArray();
3、注意:字符串每个单词之间可能有多个空格,如 [ad dfa fgs]
// 朴素写法
String[] strs = in.readLine().split(" ");
for (String s : strs) {
if (s.length() == 0)
continue;
...
}
// 正则表达式
String[] strs = in.readLine().split("\\s+"); // 以一个或多个空白符分割为数组
\\s
表示空白字符(包括空格、制表符、换行符等)。+
表示匹配前面的元素一次或多次。
卡码网KamaCoder练习题
https://kamacoder.com/
1.多行输入,每行两个整数
https://kamacoder.com/problempage.php?pid=1000
\1. A+B问题I
时间限制:2.000S 空间限制:32MB
题目描述
你的任务是计算a+b。
输入描述
输入包含一系列的a和b对,通过空格隔开。一对a和b占一行。
输出描述
对于输入的每对a和b,你需要依次输出a、b的和。
如对于输入中的第二对a和b,在输出中它们的和应该也在第二行。
输入示例
3 4
11 40
输出示例
7
51
方法
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
String s = sc.nextLine();
int a = Integer.parseInt(s.split(" ")[0]);
int b = Integer.parseInt(s.split(" ")[1]);
System.out.println(a + b);
}
}
}
快读模板
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
String[] strs = s.split(" ");
out.println(Integer.valueOf(strs[0]) + Integer.valueOf(strs[1]));
}
out.flush();
}
}
2.多行数据,每组第一行为n,之后输入n行两个整数
https://kamacoder.com/problempage.php?pid=1001
A+B问题II
内存限制:32 MB,时间限制:1.000 S
题目描述
计算a+b,但输入方式有所改变。
输入
第一行是一个整数N,表示后面会有N行a和b,通过空格隔开。
输出
对于输入的每对a和b,你需要在相应的行输出a、b的和。
如第二对a和b,对应的和也输出在第二行。
样例输入 复制
2
2 4
9 21
样例输出 复制
6
30
提示
注意,测试数据不仅仅一组。也就是说,会持续输入N以及后面的a和b
import java.io.PrintWriter;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
PrintWriter out = new PrintWriter(System.out);
while (in.hasNext()) {
int n = in.nextInt();
for (int i = 0; i < n; i++) {
int a = in.nextInt();
int b = in.nextInt();
out.println(Integer.valueOf(a + b));
}
}
out.flush();
}
}
快读
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
int n = Integer.valueOf(s);
for (int i = 0; i < n; i++) {
String[] strs = in.readLine().split(" ");
out.println(Integer.valueOf(strs[0]) + Integer.valueOf(strs[1]));
}
}
out.flush();
}
}
3.若干行输入,每行输入两个整数,遇到特定条件终止
https://kamacoder.com/problempage.php?pid=1002
\2. A+B问题II
时间限制:1.000S 空间限制:32MB
题目描述
计算a+b,但输入方式有所改变。
输入描述
第一行是一个整数N,表示后面会有N行a和b,通过空格隔开。
输出描述
对于输入的每对a和b,你需要在相应的行输出a、b的和。
如第二对a和b,对应的和也输出在第二行。
输入示例
2
2 4
9 21
输出示例
6
30
提示信息
注意,测试数据不仅仅一组。也就是说,会持续输入N以及后面的a和b
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(System.in);
PrintWriter out = new PrintWriter(System.out);
while (in.hasNext()) {
int n = Integer.valueOf(in.nextLine());
for (int i = 0; i < n; i++) {
String[] strs = in.nextLine().split(" ");
out.println(Integer.valueOf(strs[0]) + Integer.valueOf(strs[1]));
}
}
out.flush();
}
}
快读
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
int n = Integer.valueOf(s);
for (int i = 0; i < n; i++) {
String[] strs = in.readLine().split(" ");
out.println(Integer.valueOf(strs[0]) + Integer.valueOf(strs[1]));
}
}
out.flush();
}
}
4.若干行输入,遇到0终止,每行第一个数为N,表示本行有N个数
https://kamacoder.com/problempage.php?pid=1003
\4. A+B问题IV
时间限制:1.000S 空间限制:32MB
题目描述
你的任务是计算若干整数的和。
输入描述
每行的第一个数N,表示本行后面有N个数。
如果N=0时,表示输入结束,且这一行不要计算。
输出描述
对于每一行数据需要在相应的行输出和。
输入示例
4 1 2 3 4
5 1 2 3 4 5
0
输出示例
10
15
答
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
String[] strs = s.split(" ");
int n = Integer.valueOf(strs[0]);
if (n == 0)
break;
int sum = 0;
for (int i = 0; i < n; i++) {
sum += Integer.valueOf(strs[i + 1]);
}
out.println(sum);
}
out.flush();
}
}
5.若干行输入,每行包括两个整数a和b,由空格分隔,每行输出后接一个空格
https://kamacoder.com/problempage.php?pid=1004
\5. A+B问题VII
时间限制:1.000S 空间限制:32MB
题目描述
你的任务是计算两个整数的和。
输入描述
输入包含若干行,每行输入两个整数a和b,由空格分隔。
输出描述
对于每组输入,输出a和b的和,每行输出后接一个空行。
输入示例
2 4
11 19
输出示例
6
30
答
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.Buffer;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
int a = Integer.valueOf(s.split(" ")[0]);
int b = Integer.valueOf(s.split(" ")[1]);
out.println(a + b);
out.println(" ");
}
out.flush();
}
}
6.多组n行数据,每行先输入一个整数N,然后在同一行内输入M个整数,每组输出之间输出一个空行。
\6. A+B问题VIII
时间限制:1.000S 空间限制:32MB
题目描述
你的任务是计算若干整数的和。
输入描述
输入的第一行为一个整数N,接下来N行每行先输入一个整数M,然后在同一行内输入M个整数。
输出描述
对于每组输入,输出M个数的和,每组输出之间输出一个空行。
输入示例
3
4 1 2 3 4
5 1 2 3 4 5
3 1 2 3
输出示例
10
15
6
提示信息
注意以上样例为一组测试数据,后端判题会有很多组测试数据,也就是会有多个N的输入
例如输入可以是:
3
4 1 2 3 4
5 1 2 3 4 5
3 1 2 3
3
4 1 2 3 4
5 1 2 3 4 5
3 1 2 3
输入则是
1015
6
1015
6
只保证每组数据间是有空行的。但两组数据并没有空行
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.Buffer;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
int n = Integer.valueOf(s);
for (int i = 0; i < n; i++) {
String[] strs = in.readLine().split(" ");
int m = Integer.valueOf(strs[0]);
int sum = 0;
for (int j = 0; j < m; j++) {
sum += Integer.valueOf(strs[j + 1]);
}
out.println(sum);
if (i != n - 1)
out.println(" ");
}
}
out.flush();
}
}
7.平均绩点
时间限制:1.000S 空间限制:32MB
题目描述
每门课的成绩分为A、B、C、D、F五个等级,为了计算平均绩点,规定A、B、C、D、F分别代表4分、3分、2分、1分、0分。
输入描述
有多组测试样例。每组输入数据占一行,由一个或多个大写字母组成,字母之间由空格分隔。
输出描述
每组输出结果占一行。如果输入的大写字母都在集合{A,B,C,D,F}中,则输出对应的平均绩点,结果保留两位小数。否则,输出“Unknown”。
输入示例
A B C D F
B F F C C A
D C E F
输出示例
2.00
1.83
Unknown
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.Buffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
Map<String, Integer> map = new HashMap<>();
map.put("A", 4);
map.put("B", 3);
map.put("C", 2);
map.put("D", 1);
map.put("F", 0);
String s;
while ((s = in.readLine()) != null) {
String[] strs = s.split(" ");
double sum = 0;
for (String str : strs) {
if (!map.containsKey(str)) {
sum = -1;
break;
}
sum += map.get(str);
}
if (sum == -1)
out.println("Unknown");
else{
out.printf("%.2f", sum / strs.length);
out.println("");
}
}
out.flush();
}
}
8.摆平积木
时间限制:1.000S 空间限制:32MB
题目描述
小明很喜欢玩积木。一天,他把许多积木块组成了好多高度不同的堆,每一堆都是一个摞一个的形式。然而此时,他又想把这些积木堆变成高度相同的。但是他很懒,他想移动最少的积木块来实现这一目标,你能帮助他吗?
输入描述
输入包含多组测试样例。每组测试样例包含一个正整数n,表示小明已经堆好的积木堆的个数。
接着下一行是n个正整数,表示每一个积木堆的高度h,每块积木高度为1。其中1<=n<=50,1<=h<=100。
测试数据保证积木总数能被积木堆数整除。
当n=0时,输入结束。
输出描述
对于每一组数据,输出将积木堆变成相同高度需要移动的最少积木块的数量。
在每组输出结果的下面都输出一个空行。
输入示例
6
5 2 4 1 7 5
0
输出示例
5
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String s;
while ((s = in.readLine()) != null) {
if (Integer.parseInt(s) == 0)
break;
s = in.readLine();
/**
String[] strs = s.split(" ");
int[] nums = new int[strs.length];
for(int i = 0; i < nums.length; i++){
nums[i] = Integer.parseInt(strs[i]);
}
*/
int[] nums = Arrays.stream(s.split(" "))
.mapToInt(Integer::parseInt)
.toArray();
double sum = 0.0;
for(int x : nums) sum += x;
int target = (int)(sum / nums.length);
int res = 0;
for(int x : nums)
res += Math.abs(x - target);
out.println(res / 2);
out.println("");
}
out.flush();
}
}
9.奇怪的信
时间限制:1.000S 空间限制:32MB
题目描述
有一天, 小明收到一张奇怪的信, 信上要小明计算出给定数各个位上数字为偶数的和。
例如:5548,结果为12,等于 4 + 8 。
小明很苦恼,想请你帮忙解决这个问题。
输入描述
输入数据有多组。每组占一行,只有一个整整数,保证数字在32位整型范围内。
输出描述
对于每组输入数据,输出一行,每组数据下方有一个空行。
输入示例
415326
3262
输出示例
12
10
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int sum = 0;
for (char c : str.toCharArray()) {
int num = c - '0';
if (num % 2 == 0)
sum += num;
}
out.println(sum);
out.println("");
}
out.flush();
}
}
10.运营商活动
时间限制:1.000S 空间限制:32MB
题目描述
小明每天的话费是1元,运营商做活动,手机每充值K元就可以获赠1元话费,一开始小明充值M元,问最多可以用多少天? 注意赠送的话费也可以参与到奖励规则中
输入描述
输入包括多个测试实例。每个测试实例包括2个整数M,K(2<=k<=M<=1000)。M=0,K=0代表输入结束。
输出描述
对于每个测试实例输出一个整数,表示M元可以用的天数。
输入示例
2 2
4 3
13 3
0 0
输出示例
3
5
19
提示信息
注意第三组数据「13 3」结果为什么是19呢, 13/3=4,获得4元奖励。 13%3=1,还剩下1元,4+1=5,5元继续参加奖励规则。 5/3=1,获得1元奖励。 5%3=2,剩下2元,1+2=3,3元继续参与奖励规则。 3/3=1,获得1元奖励。 3%3=0,剩下0元,1+0=1。 1元不能参与剩下奖励。所以一共可以使用的天数是 13+4+1+1=19
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
String[] strs = str.split(" ");
int m = Integer.parseInt(strs[0]), k = Integer.parseInt(strs[1]);
if(m == 0 && k == 0) break;
if (k != 0) {
// 手机每充值K元就可以获赠1元话费,注意赠送的话费也可以参与到奖励规则中
int last = m % k;
int add = m / k;
m += add;
while (add + last >= k) {
int tl = last, ta = add;
last = (tl + ta) % k;
add = (tl + ta) / k;
m += add;
}
}
out.println(m);
}
out.flush();
}
}
11.共同祖先
时间限制:1.000S 空间限制:32MB
题目描述
小明发现和小宇有共同祖先!现在小明想知道小宇是他的长辈,晚辈,还是兄弟。
输入描述
输入包含多组测试数据。每组首先输入一个整数N(N<=10),接下来N行,每行输入两个整数a和b,表示a的父亲是b(1<=a,b<=20)。小明的编号为1,小宇的编号为2。
输入数据保证每个人只有一个父亲。
输出描述
对于每组输入,如果小宇是小明的晚辈,则输出“You are my younger”,如果小宇是小明的长辈,则输出“You are my elder”,如果是同辈则输出“You are my brother”。
输入示例
5
1 3
2 4
3 5
4 6
5 6
6
1 3
2 4
3 5
4 6
5 7
6 7
输出示例
You are my elder
You are my brother
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int n = Integer.parseInt(str);
int[] nums = new int[21];
int xCount = 0, yCount = 0;
for (int i = 0; i < n; i++) {
str = in.readLine();
String[] strs = str.split(" ");
int x = Integer.parseInt(strs[0]), y = Integer.parseInt(strs[1]);
nums[x - 1] = y - 1;
}
int node = 0;
while(nums[node] != 0){
node = nums[node];
xCount++;
}
node = 1;
while(nums[node] != 0){
node = nums[node];
yCount++;
}
if (xCount == yCount) {
System.out.println("You are my brother");
} else if (xCount < yCount) {
System.out.println("You are my younger");
} else {
System.out.println("You are my elder");
}
}
out.flush();
}
}
12.打印数字图形
时间限制:1.000S 空间限制:32MB
题目描述
先要求你从键盘输入一个整数n(1<=n<=9),打印出指定的数字图形。
输入描述
输入包含多组测试数据。每组输入一个整数n(1<=n<=9)。
输出描述
对于每组输入,输出指定的数字图形。
注意:每行最后一个数字后没有任何字符。
输入示例
5
输出示例
1
121
12321
1234321
123454321
1234321
12321
121
1
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int num = Integer.parseInt(str);
String format = "%" + num + "d"; // 定义格式化字符串,用于控制输出数字的宽度
StringBuilder sb = new StringBuilder();
String s;
StringBuilder prefix = new StringBuilder(); // 用于构建每行的前缀数字
Stack<String> stack = new Stack<>();
// 构建图形的上半部分
for (int i = 1; i <= num; i++) {
prefix.append(i); // 构建前缀数字
// 构建数字后缀
for (int j = i - 1; j > 0; j--) {
sb.append(j);
}
// 插入数字前缀
sb.insert(0, String.format(format, Integer.parseInt(prefix.toString())));
stack.push(sb.toString());
out.println(sb); // 输出当前行的字符串
sb.setLength(0); // 清空StringBuilder,准备构建下一行
}
stack.pop(); // 弹出栈顶元素,因为栈顶元素是重复的最后一行
// 反向输出图形的下半部分
while (!stack.isEmpty()) {
out.println(stack.pop());
}
}
out.flush();
}
}
14.句子缩写
时间限制:1.000S 空间限制:32MB
题目描述
输出一个词组中每个单词的首字母的大写组合。
输入描述
输入的第一行是一个整数n,表示一共有n组测试数据。(输入只有一个n,没有多组n的输入)
接下来有n行,每组测试数据占一行,每行有一个词组,每个词组由一个或多个单词组成;每组的单词个数不超过10个,每个单词有一个或多个大写或小写字母组成;
单词长度不超过10,由一个或多个空格分隔这些单词。
输出描述
请为每组测试数据输出规定的缩写,每组输出占一行。
输入示例
1
ad dfa fgs
输出示例
ADF
提示信息
注意:单词之间可能有多个空格
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
for (int i = 0; i < Integer.parseInt(str); i++) {
StringBuilder sb = new StringBuilder();
// String[] strs = in.readLine().split(" ");
String[] strs = in.readLine().split("\\s+"); // 以一个或多个空白符分割为数组
for (String s : strs) {
// if (s.length() == 0)
// continue;
sb.append(s.charAt(0));
}
out.println(sb.toString().toUpperCase());
}
}
out.flush();
}
}
15.神秘字符
时间限制:1.000S 空间限制:32MB
题目描述
考古学家发现墓碑上有神秘的字符。经过仔细研究,发现原来这是开启古墓入口的方法。
墓碑上有2行字符串,其中第一个串的长度为偶数,现在要求把第2个串插入到第一个串的正中央,如此便能开启墓碑进入墓中。
输入描述
输入数据首先给出一个整数n,表示测试数据的组数。(整个输入中,只有一个n)
然后是n组数据,每组数据2行,每行一个字符串,长度大于0,小于50,并且第一个串的长度必为偶数。
输出描述
请为每组数据输出一个能开启古墓的字符串,每组输出占一行。
输入示例
2
asdf
yu
rtyu
HJK
输出示例
asyudf
rtHJKyu
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int n = Integer.parseInt(str);
for (int i = 0; i < n; i++) {
str = in.readLine();
StringBuilder sb = new StringBuilder(str);
str = in.readLine();
sb.insert(sb.length() / 2, str);
out.println(sb.toString());
}
}
out.flush();
}
}
16.位置互换
时间限制:1.000S 空间限制:32MB
题目描述
给定一个长度为偶数位的字符串,请编程实现字符串的奇偶位互换。
输入描述
输入包含多组测试数据。
输入的第一行是一个整数n,表示有测试数据。(整个输入中,只有一个n)
接下来是n组测试数据,保证串长为偶数位(串长<=50)。
输出描述
请为每组测试数据输出奇偶位互换后的结果,每组输出占一行。
输入示例
2
0aa0
bb00
输出示例
a00a
bb00
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int n = Integer.parseInt(str);
for (int i = 0; i < n; i++) {
char[] arrs = in.readLine().toCharArray();
for (int j = 0; j < arrs.length; j += 2) {
char c = arrs[j];
arrs[j] = arrs[j + 1];
arrs[j + 1] = c;
}
out.println(new String(arrs));
}
}
out.flush();
}
}
17.出栈合法性
时间限制:1.000S 空间限制:32MB
题目描述
已知自然数1,2,…,N(1<=N<=100)依次入栈,请问序列C1,C2,…,CN是否为合法的出栈序列。
输入描述
输入包含多组测试数据。
每组测试数据的第一行为整数N(1<=N<=100),当N=0时,输入结束。
第二行为N个正整数,以空格隔开,为出栈序列。
输出描述
对于每组输入,输出结果为一行字符串。
如给出的序列是合法的出栈序列,则输出Yes,否则输出No。
输入示例
5
3 4 2 1 5
5
3 5 1 4 2
0
输出示例
Yes
No
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int n = Integer.parseInt(str);
if (n == 0)
break;
str = in.readLine();
int[] nums = Arrays.stream(str.split(" "))
.mapToInt(Integer::parseInt)
.toArray();
Deque<Integer> dq = new ArrayDeque<>();
int idx = 0;
for (int i = 1; i <= n; i++) {
dq.push(i);
while (!dq.isEmpty() && nums[idx] == dq.peek()) {
idx++;
dq.pop();
}
}
if (dq.isEmpty())
out.println("Yes");
else
out.println("No");
}
out.flush();
}
}
🚀18.链表的基本操作
时间限制:1.000S 空间限制:32MB
题目描述
本题考察链表的基本操作。温馨提示:本题较为复杂,需要细心多花一些时间。
输入描述
输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数。
这一行整数是用来初始化列表的,并且输入的顺序与列表中的顺序相反,也就是说如果列表中是1、2、3那么输入的顺序是3、2、1。
第二行有一个整数m,代表下面还有m行。每行有一个字符串,字符串是“get”,“insert”,“delete”,“show”中的一种。
如果是“get”,代表获得第a个元素。(a从1开始计数)
如果是“delete”,代表删除第a个元素。(a从1开始计数)
如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e。(a从1开始计数)
“show”之后没有正数,直接打印链表全部内容。
输出描述
如果获取成功,则输出该元素;
如果删除成功,则输出“delete OK”;
如果获取失败,则输出“get fail”
如果删除失败,则输出“delete fail”
如果插入成功,则输出“insert OK”,否则输出“insert fail”。
如果是“show”,则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”
注:所有的双引号均不输出。
输入示例
3 3 2 1
21
show
delete 1
show
delete 2
show
delete 1
show
delete 2
insert 2 5
show
insert 1 5
show
insert 1 7
show
insert 2 5
show
insert 3 6
show
insert 1 8
show
get 2
输出示例
1 2 3
delete OK
2 3
delete OK
2
delete OK
Link list is empty
delete fail
insert fail
Link list is empty
insert OK
5
insert OK
7 5
insert OK
7 5 5
insert OK
7 5 6 5
insert OK
8 7 5 6 5
7
提示信息
初始化链表的元素是倒序的,这个使用题目中创建列表的方法(从头部插入)就可以了。
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import javax.swing.ListModel;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str = in.readLine();
ListNode dummy = new ListNode(-1, null);
int len = 0;
// 创建链表
String[] strarr = str.split(" ");
for (int i = 1; i < strarr.length; i++) {
String s = strarr[i];
int val = Integer.parseInt(s);
ListNode tmp = new ListNode(val);
tmp.next = dummy.next;
dummy.next = tmp;
len++;
}
// 执行操作
str = in.readLine();
int n = Integer.parseInt(str);
for (int k = 0; k < n; k++) {
str = in.readLine();
String[] strs = str.split(" ");
String operate = strs[0];
if (operate.equals("show")) {
// 如果是“show”,则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”
ListNode cur = dummy;
if (len == 0) {
out.println("Link list is empty");
continue;
}
while (cur.next != null) {
out.print(cur.next.val);
if (cur.next.next != null)
out.print(" ");
cur = cur.next;
}
out.println();
} else if (operate.equals("get")) {
// 如果是“get”,代表获得第a个元素。(a从1开始计数)
int a = Integer.parseInt(strs[1]);
if (a > len) {
out.println("get fail");
continue;
}
ListNode cur = dummy;
for (int j = 1; j < a && cur.next != null; j++) {
cur = cur.next;
}
out.println(cur.next.val);
} else if (operate.equals("insert")) {
// 如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e。(a从1开始计数)
int a = Integer.parseInt(strs[1]), e = Integer.parseInt(strs[2]);
if (a > len + 1) {
out.println("insert fail");
continue;
}
ListNode cur = dummy;
for (int j = 1; j < a && cur.next != null; j++) {
cur = cur.next;
}
ListNode tmp = new ListNode(e);
tmp.next = cur.next;
cur.next = tmp;
out.println("insert OK");
len++;
} else if (operate.equals("delete")) {
// 如果是“delete”,代表删除第a个元素。(a从1开始计数)
int a = Integer.parseInt(strs[1]);
if (a > len) {
out.println("delete fail");
continue;
}
ListNode cur = dummy;
for (int j = 1; j < a && cur.next != null; j++) {
cur = cur.next;
}
cur.next = cur.next.next;
out.println("delete OK");
len--;
}
}
out.flush();
}
}
class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
19.单链表反转
时间限制:10.000S 空间限制:128MB
题目描述
根据一个整数序列构造一个单链表,然后将其反转。
例如:原单链表为 2 3 4 5 ,反转之后为5 4 3 2
输入描述
输入包括多组测试数据,每组测试数据占一行,第一个为大于等于0的整数n,表示该单链表的长度,后面跟着n个整数,表示链表的每一个元素。整数之间用空格隔开
输出描述
针对每组测试数据,输出包括两行,分别是反转前和反转后的链表元素,用空格隔开
如果链表为空,则只输出一行,list is empty
输入示例
5 1 2 3 4 5
0
输出示例
1 2 3 4 5
5 4 3 2 1
list is empty
提示信息
本题用数组,也是可有过的,输入一遍数组,然后倒叙输出。不过建议大家用本题来链表操作
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
String[] strs = str.split(" ");
int n = Integer.parseInt(strs[0]);
if (n == 0) {
out.println("list is empty");
continue;
}
ListNode dummy = new ListNode(-1, null);
ListNode cur = dummy;
for (int i = 0; i < n; i++) {
ListNode tmp = new ListNode(Integer.parseInt(strs[i + 1]));
tmp.next = cur.next;
cur.next = tmp;
cur = tmp;
}
cur.next = null;
cur = dummy.next;
while (cur != null) {
out.print(cur.val);
if (cur.next != null)
out.print(" ");
cur = cur.next;
}
out.println();
cur = dummy.next;
ListNode newhead = rev(cur);
cur = newhead;
while (cur != null) {
out.print(cur.val);
if (cur.next != null)
out.print(" ");
cur = cur.next;
}
out.println();
}
out.flush();
}
public static ListNode rev(ListNode node) {
ListNode dummy = new ListNode(-1, null);
while (node != null) {
ListNode next = node.next;
node.next = dummy.next;
dummy.next = node;
node = next;
}
return dummy.next;
}
}
class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
🚀22.二叉树的遍历
时间限制:1.000S 空间限制:128MB
题目描述
给出一个n个节点的二叉树,请求出二叉树的前序遍历,中序遍历和后序遍历。
输入描述
第一位一个整数n(0<n<=26),表示二叉树有n个节点,以下n行,每行第一个为一个大写字母表示节点,后面为两整数,第一个表示左儿子序号
第二个表示右儿子序号,如果该序号为0表示没有。 (例如下面示例中,F序号为1,C序号为2,E序号为3,A序号为4,D序号为5,G序号为6,B序号为7)
输出描述
共三行,第一行为二叉树的前序遍历,第二行为中序遍历,第三行为后序遍历
输入示例
7
F 2 3
C 4 5
E 0 6
A 0 0
D 7 0
G 0 0
B 0 0
输出示例
FCADBEG
ACBDFEG
ABDCGEF
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String str;
while ((str = in.readLine()) != null) {
int n = Integer.parseInt(str);
String[] lines = new String[n];
for (int i = 0; i < n; i++) {
lines[i] = in.readLine();
}
int rootIndex = 1;
TreeNode root = buildTree(lines, rootIndex);
out.println(preOrder(root));
out.println(inOrder(root));
out.println(postOrder(root));
}
out.flush();
}
// dfs 构造二叉树,lines为按序号排序的节点,以及左右子树节点序号值
public static TreeNode buildTree(String[] lines, int index) {
String[] items = lines[index - 1].split(" ");
char val = items[0].charAt(0);
int leftIndex = Integer.parseInt(items[1]);
int rightIndex = Integer.parseInt(items[2]);
TreeNode root = new TreeNode(val);
if (leftIndex != 0)
root.left = buildTree(lines, leftIndex);
if (rightIndex != 0)
root.right = buildTree(lines, rightIndex);
return root;
}
public static String preOrder(TreeNode root) {
if (root == null)
return "";
return root.val + preOrder(root.left) + preOrder(root.right);
}
public static String inOrder(TreeNode root) {
if (root == null)
return "";
return inOrder(root.left) + root.val + inOrder(root.right);
}
public static String postOrder(TreeNode root) {
if (root == null)
return "";
return postOrder(root.left) + postOrder(root.right) + root.val;
}
}
class TreeNode {
char val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(char val) {
this.val = val;
}
TreeNode(char val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}