LuoguP5238 整数校验器 题解

Content

给定两个整数 \(l,r\),再给定 \(T\) 个整数,请判断对于每个整数 \(x\),是否满足以下要求:

  • \(x\in[l,r]\)
  • \(x\) 格式合法。

数据范围:\(-2^{63}\leqslant l,r\leqslant 2^{63}-1,0\leqslant T\leqslant 512\)

Solution

一道模拟题。

我们先来判断这个数是否格式合法。格式不合法的情况有以下几种:

  • 只有单独的一个负号。
  • \(0\) 开头且长度不为 \(1\)
  • 以一个负号和一个 \(0\) 开头。

这些特判完以后我们就来看这个数如何处理。由于这个数可能很大,所以在 C++ 语言中直接用普通的整型变量读入肯定是不科学的。所以一开始只能够用字符串来读入,然后就开始将其转化为数字,注意一定要看是否会超过 \(\textsf{long long}\) 的范围,一旦超过了就得结束此次判断。

如果转换完了,再看这个数字是否在这个范围里面。

Code

int t;
long long l, r;

bool judge1(string s) {
	int len = s.size();
	if(len != 1 && s[0] == '0') return 1;
	if(len == 1 && s[0] == '-') return 1;
    if(s[0] == '-' && s[1] == '0') return 1;
	return 0;
}

int main() {
	l = Rll, r = Rll, t = Rint;
	while(t--) {
		string s; cin >> s;
		int len = s.size(), flag = 1; unsigned long long x = 0ll, f = 1ll;
		if(judge1(s)) puts("1");
		else {
			if(s[0] == '-') f = -1ll;
			for(int i = (s[0] == '-' ? 1 : 0); i < len; ++i) {
				if(x > 922337203685477580ll || (x == 922337203685477580ll && ((f == 1ll && s[i] > '7') || (f == -1ll && s[i] > '8')))) {flag = 0; break;}
				x = x * 10 + s[i] - '0';
			}
			long long res = x * f;
			if(!flag || (res < l || res > r)) puts("2");
			else puts("0");
		}
	}
	return 0;
}
posted @ 2021-12-16 14:46  Eason_AC  阅读(19)  评论(0)    收藏  举报