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;
}