Calculate a+b and output the sum in standard format – that is, the digits must be separated into groups of three by commas (unless there are less than four digits).
Each input file contains one test case. Each case contains a pair of integers a and b where -10^6 <= a,b <= 10^6 The numbers are separated by a space.
For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.
-1000000 9
-999,991
给定两个数a和b,计算他们的和,并每三个添加分隔符(在千分位添加分隔符)
由于都是在int范围内,所以不用考虑溢出的问题。(最大2×10^6)
首先有一个最简单的方法,就是掏出Java里面一个非常有用的类——DecimalFormat
(PS:在PAT考试里面,对于时间限制要求不高的20分题目,用Java往往可以很快秒杀。只要用好String、BigInteger、DecimalFormat等类)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.StringTokenizer;
public class Main {
static final int BUFFER_SIZE = 8192 * 25;
static BufferedReader br;
static StringTokenizer tokenizer;
static void initInput(InputStream in) throws Exception {
br = new BufferedReader(new InputStreamReader(in), BUFFER_SIZE);
tokenizer = new StringTokenizer("");
}
static String next() throws Exception {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(br.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws Exception {
return Integer.parseInt(next());
}
static PrintWriter pw;
public static void main(String[] args) throws Exception {
initInput(System.in);
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out), BUFFER_SIZE));
/*正式代码开始*/
int a = nextInt(),b=nextInt();
int c = a+b;
DecimalFormat df = new DecimalFormat("#,###");
//如果要求按四位分割,就改为#,####即可
pw.println(df.format(c));
/*结束*/
pw.flush();
}
}
如图,核心代码只有四行。(关于为什么IO要这么写的说明附在文后,并会给出一个模版)
不出意料,耗时和内存都很高,这是用Java写PAT的常态(Python耗时都比Java强。但是不妨碍好用~过了就行)
正常考试我们1分钟拿到分就跑了,但是作为学习阶段应该再认真思考一下到底应该怎么做。
对于一个数 1234567890 (求和之后),应该表示为1,234,567,890
如果将这个数转化为字符串,其每一位的字符与下标对应关系如下:
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 0
可以看出,在打印str[0] 、str[3]、str[6]字符之后需要打印一个逗号。
通过观察规律,设下标为i,则满足条件 (i+1)%3==len%3 时需要打印一个逗号。如果 i 是最后一位(即 i==len-1 )不需要打印。如果是负数,跳过即可,同样符合这个规律。
如: -1234567
0 1 2 3 4 5 6 7
#include
#include
using namespace std;
int main() {
int a, b;
scanf("%d %d", &a, &b);
string s = to_string(a + b);
for (int i = 0; i < s.length(); i++) {
printf("%c", s[i]);
if (s[i] != '-' && (i + 1) % 3 == s.length() % 3 && i != s.length() - 1)
printf(",");
}
return 0;
}
刚开始的三四十道题我也是采用Java答题,但是后面部分题目实在是无法通过。(限时300ms以下的题目,用Java通过几乎 不可能),下面对于Java的技巧,也仅仅是在一定程度上改良,如果只是自己学着练练题目,可以用Java写,但是如果是要参加考试,请趁早转行。原因在于:
1、Pat官方解释,呵呵,就这样。
2、PTA的判题系统里Java相关的编译程序已经许久 没有维护,Java虚拟机的启动时间也被算在程序运行时间内。
一、如果采用Java答题
Java属于先编译后解释的语言,虽然由.java编译成.class文件的时间不算在内,但是Java虚拟机启动(长达50ms+)的时间会被算在里面。如果采用了低效的IO方法,效果会更差。相比而言,纯解释型语言(如Python),反倒更快(相比较而言)。
下面的几个提升运行速度的方法,实际效果依次减弱。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)));
Scanner虽然方便好用,但是效率极差,参见
Fast Input for Java
某使用Java打国际acm选手做的实验
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
使用BufferedWriter封装转化而来的System.out,可以提高效率,再使用PrintWriter封装,可以方便使用print、printf、println等方法。
static final int BUFFER_SIZE = 8192 * 25;
忘了是在哪里见过一次别人这么写,实际 效果存疑, 可能并无卵用。
综上几条可以得出Java里面最高效的读写模版如下:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Main{
static final int BUFFER_SIZE = 8192*25;
static BufferedReader br;
static StringTokenizer tokenizer;
static void initInput(InputStream in) throws Exception {
br = new BufferedReader(new InputStreamReader(in), BUFFER_SIZE);
tokenizer = new StringTokenizer("");
}
static String next() throws Exception{
while(!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(br.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws Exception {
return Integer.parseInt(next());
}
static double nextDouble() throws Exception{
return Double.parseDouble(next());
}
static PrintWriter pw;
public static void main(String[] args) throws Exception {
initInput(System.in);
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out),BUFFER_SIZE));
/*在这里插入你的代码*/
int i = nextInt(); //读取一个整数
String s = next(); //读取一个字符串
double d = nextDouble(); //读取一个浮点数
pw.flush();
}
}
注:StringTokenizer的默认分隔符是空格和换行,如果需要其他方式,还是用next()读取字符串后使用spilt方法比较合适。
二、如果采用C语言答题
改用C++,没有STL基本上不能活。
三、如果采用C++答题
C++没什么好说的,一般来说没有大问题(很多时候 ,Java需要采用最优化的算法才能过,C++甚至暴力就行了)
只有几点需要注意:
当然了,有的时候图方便可以采用一点低效的方法。反正错了还可以再改(PAT考试不罚时)(逃)