目录
题目链接:1.平方差 - 蓝桥云课 (lanqiao.cn)
思路
暴力偷分
发现规律
发现蹊跷
总结
题目链接:1.平方差 - 蓝桥云课 (lanqiao.cn)
思路
咱就是说,写蓝桥杯的题目的第一件事情是什么,那就是不管三七二十一先暴力一下把能拿到的分数拿到再说没毛病。
暴力偷分
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;public class Main {public static void main(String[] args) throws IOException{StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));st.nextToken();int L = (int) st.nval;st.nextToken();int R = (int) st.nval;int res = 0;for (int i = L; i <= R; i++) {if (have(i)) {res++;}}System.out.println(res);}public static boolean have(int x) {for (int i = 1; i <= x; i++) {for (int j = 0; j < x; j++) {if (x == i*i - j*j) {return true;}}}return false;}
}
嘿嘿
我不要脸!!~~~~~
发现规律
如果大家寻找一下数的规律
比如,1~16中满足题目要求的数字有
可以:1,3,4,5,7,8,9,11,12,13,15,16
不可以:2,6,10,14
满足要求的是奇数或者2的偶数倍
那么我就写下了如下的代码
// 1:无需package
// 2: 类名必须Main, 不可修改
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;public class Main {public static void main(String[] args) throws IOException{// 得出结论是,奇数和二的偶数倍都可以StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));st.nextToken();int L = (int) st.nval;st.nextToken();int R = (int) st.nval;int res = 0;for (int i = L; i <= R; i++) {// 遍历所有数看有那些数满足通过观察得到的规律if (i % 2 != 0 || i % 4 == 0) {res++;}}System.out.println(res);}
}
为什么,为什么只通过了90%,我的代码已经很完美了啊,啊啊啊啊啊啊啊,根本想不出来优化的方法了啊,难道我就要放弃了吗,放弃了吗,放弃了吗.........
发现蹊跷
我也是服了,你们知道为什么我这里的输入流一直使用的是StreamTokenizer吗,因为在输入的数据量比较大的情况下它的效率更高,可以提升速度,但是我真的是服啦!!!!!!!!记住前任的话,有利有弊,你得到了什么必然会失去什么。查了一下资料才知道这个小东西使用navl读取的数据默认都是double类型,如果我们long类型的长度已经超过了double类型的精度那么对不起,听天由命吧。所以我老老实实用回了Scanner万金油老哥┭┮﹏┭┮爱了。
package src;//1:无需package
//2: 类名必须Main, 不可修改
import java.util.Scanner;public class Main {public static void main(String[] args) {// 得出结论是,奇数和二的偶数倍都可以Scanner sc = new Scanner(System.in);long L = sc.nextLong();long R = sc.nextLong();long res = 0L;res += (R + 1)/2 - L/2;res += R / 4 - (L - 1)/4;System.out.println(res);}
}
那么有些大聪明可能就不服了,写出了如下的处理方式
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));st.nextToken();String lString = st.sval;// 用于等一下的测试效果System.out.println(lString);long L = Long.parseLong(lString);st.nextToken();String rString = st.sval;// 用于等一下的测试效果System.out.println(rString);long R = Long.parseLong(rString);
恭喜你,思路很棒,但是现实很骨感。。。。o(╥﹏╥)o
控制台是这样的
1 16
null
Exception in thread "main" java.lang.NumberFormatException: null
at java.lang.Long.parseLong(Long.java:552)
at java.lang.Long.parseLong(Long.java:631)
at src.Main.main(Main.java:15)
为什么呢这里会是null呢wdf***?
因为默认情况下,StreamTokenizer将把数字解析为double类型,并将其值存储在nval
字段中。如果词素被认定为数字,sval
字段将为null。
所以这里就真的可以放弃StreamTokenizer,当然这个是可以修改处理方式的,但是有这时间不如直接换成Scanner更加爽
总结
累了,记住遇到这种类似数学的问题,先找规律,如果比较大的测试用例超时,优化代码,如果答案错误在代码逻辑没问题的情况下,看看精度问题。
下班!!!喽~~