2023年蓝桥杯省赛——平方差

目录

题目链接: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更加爽

总结

        累了,记住遇到这种类似数学的问题,先找规律,如果比较大的测试用例超时,优化代码,如果答案错误在代码逻辑没问题的情况下,看看精度问题。

下班!!!喽~~

 

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenJGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值