解题报告:洛谷 P5238 整数校验器

版权声明:转载请附带原文链接,请勿随意删除原文内容,允许少量格式和/或内容修改,谢谢! https://blog.csdn.net/weixin_37661548/article/details/88089891

题目链接

算法

  • 字符串

参考代码(Accepted 100)

#include <bits/stdc++.h>
using namespace std;

long long l,r,sres;
unsigned long long res;
int length,T;
char input[200000];

bool judge()
{
	unsigned long long tl = -l,tr = r; //左界是负数,取绝对值即取反。
	for (int i = 0;i <= length - 1;++i)
	{
		if (input[i] == '-') continue;
		res = (res << 1) + (res << 3) + input[i] - '0';
		sres = (sres << 1) + (sres << 3) + input[i] - '0';
	}
	if (l > 0 && res < -tl) return true;
	else if (r < 0 && (input[0] != '-' || res < -tr)) return true;
	//同正同负就不用取反了。
	else if (input[0] == '-' && res <= tl) return false;
	else if (input[0] != '-' && res <= tr) return false;
	else return true;
}

int main()
{
	scanf("%lld%lld%d",&l,&r,&T);
	for (int i = 1;i <= T;++i)
	{
	 	res = 0;
		scanf("%s",input);
		length = strlen(input);
		if (length == 1 && input[0] == '-')          puts("1");
		else if (input[0] == '-' && input[1] == '0') puts("1");
		else if (length > 1 && input[0] == '0')  	 puts("1");
		else if (length > 20 && input[0] == '-') 	 puts("2");
		else if (length > 19 && input[0] != '-') 	 puts("2");
		else if (judge())                        	 puts("2");
		else                                      	 puts("0");
	}
}

分析

本题需要考虑的细节有很多,例如:

  • 单独一个“-”是不合法的;
  • 输入的数字在singed long long边界时。测试点#1为此而生。

作者一开始没有考虑到只有一个负号的情况。

对于第二个细节,以下数据可以卡掉Unaccepted 100的程序:

-9223372036854775807 9223372036854775807 1
9223372036854775810

正解输出2,没考虑边界的输出0。

处理方法是,若输入值为为负数,比较它和左界的绝对值大小;若输入值为非负数,比较它和右界的绝对值大小

但这样还没完,以下数据可以把部分Accepted 100程序卡掉:

2 3 1
1

就是当左右界全正或全负的情况,洛谷的数据没考虑。像这样加个特判即可:

if (l > 0 && res < -tl) return true;
else if (r < 0 && (input[0] != '-' || res < -tr)) return true;

另外,9223372036854775810是爆long long的,因此用ull存输入值,左右界也应转为ull再比较。

如果读入数字的位数已经超过long long的最大位数(19),直接判断越界即可。

欢迎Hack作者的程序。

若有谬误,敬请斧正。

猜你喜欢

转载自blog.csdn.net/weixin_37661548/article/details/88089891