题目描述
有些时候需要解决这样一类问题:判断一个数 xx 是否合法。
xx 合法当且仅当其满足如下条件:
- xx 格式合法,一个格式合法的整数要么是 00,要么由一个可加可不加的负号,一个 11 到 99 之间的数字,和若干个 00 到 99 之间的数字依次连接而成。
- xx 在区间 [l,r][l,r] 范围内(即 l \le x \le rl≤x≤r)。
你需要实现这样一个校验器,对于给定的 l, rl,r,多次判断 xx 是否合法。
输入输出格式
输入格式:
第一行三个整数 l,r,Tl,r,T,表示校验器的校验区间为 [l,r][l,r],以及需要校验的 xx 的个数。
接下来 TT 行,每行一个 xx,表示要校验的数,保证 xx 长度至少为 11 且仅由 '0'~'9' 及 '-' 构成,且 '-' 只会出现在第一个字符。
输出格式:
输出共 T 行,每行一个整数,表示每个 xx 的校验结果。
校验结果规定如下:00 表示 xx 合法;11 表示 xx 格式不合法;22 表示 xx 格式合法且不在 [l,r][l,r] 区间内。
输入输出样例
输入样例#1
-3 3 4 0 00 -0 100000000000000000000
输出样例#1
0 1 1 2
说明
对于 100\%100% 的数据,0 \le T \le 5120≤T≤512,l,rl,r 在 6464 位有符号整型范围内(即 -2^{63}\le l \le r \le 2^{63}-1−263≤l≤r≤263−1)。
保证输入文件大小不超过 \text{128KB}128KB。数据在 linux 下生成,没有 '\r' 字符。
以下为部分特殊限制(互不包含):
- 有 5\%5% 的数据,T=0T=0。
- 有 25\%25% 的数据,保证 xx 格式一定合法。
- 有 30\%30% 的数据,保证如果 xx 格式合法,那么 xx 一定在 6464 位有符号整形范围内。
其中有一个不计分的hack测试点,用于考察long long边界数字的判断,如果是100分UnAC的话,那么可能是你没有考虑这一种情况。
思路
模拟,不过有很多细节,读入字符串str,先判断合不合法,然后转成数字检查是否在区间[l,r]里。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
long long int n,r,l,s,len;
unsigned long long int x;
char str[257];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
register long long int i,j;
cin>>l>>r>>n;
while(n--)
{
x=0,i=0,j=0;
cin>>str+1;
len=strlen(str+1);
if(str[1]=='0' && len!=1)//如果形如0000这样的
{
cout<<1<<endl;//不合法
continue;
}
if(str[1]=='-')//如果是负数
{
if(len==1)//单独一个负号不合法
{
cout<<1<<endl;
}
else if(str[2]=='0')//-0不合法
{
cout<<1<<endl;
}
else if(len>20)//过大了
{
cout<<2<<endl;
}
else//转数
{
int position(2);
while(position<=len)
{
x=x*10+(int)str[position]-48;
position++;
}
x=-x;//注意这是个负数
if(x>=l)//检查是否在区间里,只需要比较l,因为x是负数
{
cout<<0<<endl;
}
else
{
cout<<2<<endl;
}
}
}
else//整数
{
if(len>19)//长度过大
{
cout<<2<<endl;
}
else//转数
{
int position(1);
while(position<=len)
{
x=x*10+(int)str[position]-48;
position++;
}
if(x<=r)//到r就行了,因为是正数
{
cout<<0<<endl;
}
else
{
cout<<2<<endl;
}
}
}
}
return 0;
}