第四个小时才从睡梦中醒来。。。匆匆忙忙乱搞了一份交上去。。TLE…
A + B = C
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1655 Accepted Submission(s): 363
Special Judge
Problem Description
Hi everyone! Welcome to the Stage 7 of this series of training contests. Cuber QQ is the problem settler of this contest; he has prepared 11 problems for you and wishes you to enjoy it. Good luck!
As the first problem of this contest, Cuber QQ thought that it’s reasonable to start with an easy one, so he modified the famous A + B problem by a little bit, so that it’s easy enough but not that trivial.
Given a,b,c , find an arbitrary set of x,y,z such that a⋅10x+b⋅10y=c⋅10z and 0≤x,y,z≤106.
Input
The input consists of multiple test cases, starting with an integer t (1≤t≤100), denoting the number of test cases.
For each test case, there are three space-separated integers, a,b,c respectively (1≤a,b,c≤10100000).
Output
For each test case, please output three space-separated integers x,y,z. If there are multiple solutions, print any of them.
In case there are no solutions, please output −1 as a single line.
Sample Input
3
23 39 62
2 31 51
1 1 1
Sample Output
0 0 0
1 0 0
-1
Solution
当时用了BigInteger 。当时的想法是,如果存在解,则一定至少有一个可以为0,分别枚举x,y,z,另其为0。
再去解剩下两个,从0到100000 枚举其中一个,用大数减法验证是否满足等式
结果超时。。
后来换了一种方法,先将三个数补成长度相同,将大数相等改成了hash判断
依然TLE
AC 了的做法: 补零到 a,b,c 长度相等之后, 可能的情况只有四种:
b 和 (c−a) 除尾0外 完全相同
b 和(10·c−a)除尾0外 完全相同
a 和(c−b)除尾0外 完全相同
a 和 (10·c−b)除尾0外 完全相同
分别对四种情况进行判断即可
值得注意的是,这里的相减最好手动模拟。不然。。。。。
尝试将模拟相减的代码改成BigInteger后…

耗时108秒 !

而模拟的值用了733毫秒
仔细分析BigInteger源码后
发现他的constructor 实在费劲
发现问题后进行测试,果然。。 主要时间都在构造解析字符串上
而真正的运算花费的时间是极少的
构造10^200000的数字就已经要一秒多了。。。
这也让我对BigInteger失望了一波
【BigInteger sucks !】
不过想了想,之所以设计者弄得这么复杂,可能是为了方便其他运算,提高其他运算的效率吧(瞎猜)
AC Code
/*
* Copyright (c) 2019 Ng Kimbing, HNU, All rights reserved. May not be used, modified, or copied without permission.
* @Author: Ng Kimbing, HNU.
* @LastModified:2019-08-12 T 12:09:46.922 +08:00
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import static ACMProblems.ACMIO.*;
public class Main {
private static int maxn = 100005;
private static String a, b, c;
private static int x, y, z;
private static char[] lotOfZeros;
private static String subtract(String a, String b) {
char[] aStr = a.toCharArray();
char[] bStr = b.toCharArray();
char[] res = new char[aStr.length];
for (int i = 0; i < aStr.length; ++i) {
res[i] = (char) (aStr[i] - bStr[i] + '0');
}
for (int i = aStr.length - 1; i > 0; --i)
if (res[i] < '0') {
res[i] += 10;
--res[i - 1];
}
int pos = 0;
while (pos < res.length && res[pos] == '0')
++pos;
if (pos == res.length)
return null;
return new String(res, pos, res.length - pos);
}
private static String trim(String s) {
int len = s.length();
int st = 0;
while (st < len && s.charAt(st) == '0') {
st++;
}
while (st < len && s.charAt(len - 1) == '0') {
len--;
}
return s.substring(st, len);
}
private static int check(String a, String longer) {
String aTrim = trim(a);
String bTrim = trim(longer);
if (aTrim.equals(bTrim))
return a.length() - b.length();
return -1;
}
private static int check(String a, String b, String c) {
// if c < a return -1
if (a.length() > c.length() || (a.length() == c.length() && a.compareTo(c) > 0))
return -1;
// String d = new BigInteger(c).subtract(new BigInteger(a)).toString();
String d = subtract(c, a); // d = c-a
if (d == null)
return -1;
// equals except trailing zero
return check(d, b);
}
private static void printAnswer(int x, int y, int z) {
// fix the answer.
int min = Math.min(Math.min(x, y), z);
x -= min;
y -= min;
z -= min;
int e6 = 1000000;
if (x > e6 || y > e6 || z > e6)
out.println(-1);
else
out.println(x + " " + y + " " + z);
}
private static void init() {
lotOfZeros = new char[maxn];
for (int i = 0; i < lotOfZeros.length; ++i)
lotOfZeros[i] = '0';
}
private static String getZeros(int n) {
return new String(lotOfZeros, 0, n);
}
private static void makeSame() {
x = 0;
y = 0;
z = 0;
int maxLen = Math.max(Math.max(a.length(), b.length()), c.length());
int foo = maxLen - a.length();
a += getZeros(foo);
x += foo;
foo = maxLen - b.length();
b += getZeros(foo);
y += foo;
foo = maxLen - c.length();
c += getZeros(foo);
z += foo;
}
public static void main(String[] args) throws Exception {
setStream(new FileInputStream("1001"));
setOutputStream(new FileOutputStream("my1001"));
BingOJ.setProperties("my1001", "1001.a", 2000);
init();
int tt = nextInt();
while (tt-- != 0) {
a = next();
b = next();
c = next();
makeSame();
int ans = 0;
if ((ans = check(a, b, c)) != -1) {
printAnswer(x, y + ans, z);
continue;
}
if ((ans = check("0" + a, "0" + b, c + "0")) != -1) {
printAnswer(x, y + ans, z + 1);
continue;
}
if ((ans = check(b, a, c)) != -1) {
printAnswer(x + ans, y, z);
continue;
}
if ((ans = check("0" + b, "0" + a, c + "0")) != -1) {
printAnswer(x + ans, y, z + 1);
continue;
}
out.println(-1);
}
out.flush();
BingOJ.specialJudge();
}
}
本文探讨了ACM竞赛中A+B问题的多种解法,包括使用BigInteger进行大数操作的初试方案及其存在的问题,最终通过优化算法,采用手动模拟减法和比较,实现了高效求解。
209

被折叠的 条评论
为什么被折叠?



