题目链接: P5238 整数校验器
题目描述
有些时候需要解决这样一类问题:判断一个数 xxx 是否合法。
xxx 合法当且仅当其满足如下条件:
- xxx 格式合法,一个格式合法的整数要么是 000,要么由一个可加可不加的负号,一个 111 到 999 之间的数字,和若干个 000 到 999 之间的数字依次连接而成。
- xxx 在区间 [l,r][l,r][l,r] 范围内(即 l≤x≤rl \le x \le rl≤x≤r)。
你需要实现这样一个校验器,对于给定的 l,rl, rl,r,多次判断 xxx 是否合法。
输入输出格式
输入格式:
第一行三个整数 l,r,Tl,r,Tl,r,T,表示校验器的校验区间为 [l,r][l,r][l,r],以及需要校验的 xxx 的个数。
接下来 TTT 行,每行一个 xxx,表示要校验的数,保证 xxx 长度至少为 111 且仅由 '0'~'9' 及 '-' 构成,且 '-' 只会出现在第一个字符。
输出格式:
输出共 TTT 行,每行一个整数,表示每个 xxx 的校验结果。
校验结果规定如下:000 表示 xxx 合法;111 表示 xxx 格式不合法;222 表示 xxx 格式合法且不在 [l,r][l,r][l,r] 区间内。
输入输出样例
输入样例#1: 复制
-3 3 4 0 00 -0 100000000000000000000
输出样例#1: 复制
0 1 1 2
说明
对于 100%100\%100% 的数据,0≤T≤5120 \le T \le 5120≤T≤512,l,rl,rl,r 在 646464 位有符号整型范围内(即 −263≤l≤r≤263−1-2^{63}\le l \le r \le 2^{63}-1−263≤l≤r≤263−1)。
保证输入文件大小不超过 128KB\text{128KB}128KB。数据在 linux 下生成,没有 '\r' 字符。
以下为部分特殊限制(互不包含):
- 有 5%5\%5% 的数据,T=0T=0T=0。
- 有 25%25\%25% 的数据,保证 xxx 格式一定合法。
- 有 30%30\%30% 的数据,保证如果 xxx 格式合法,那么 xxx 一定在 646464 位有符号整形范围内。
这是道考察字符串的一道题,主要的知识点是字符串转数字,做这道题遇到的问题是,当一个数特别大的时候会超范围,改变量类型也不行。不能完全通过样例。
下面展示字符串转数字的代码:
#include<sstream>//需要引入的头文件
int str2num(string s){
int num;
stringstream ss(s);
ss>>num;
return num;
}
以下bug代码:
#include<iostream>
#include<cstdio>
#include <sstream>
#include <string>
using namespace std;
double str2num(string s){
double num;
stringstream ss(s);
ss>>num;
return num;
}
int main(){
double l,r,T;
cin>>l>>r>>T;
getchar();
for(int i=0;i<T;i++){
//cout<<"i="<<i<<endl;
string n;
getline(cin,n);
//getchar();
//cout<<"n="<<n<<endl;
//cout<<n<<endl;
if(n.size()>=2){
if(n[0]=='0'){
cout<<'1'<<endl;
continue;
}else if(n[0]=='-'&&n[1]=='0'){
cout<<'1'<<endl;
continue;
}
}
//int n;
//cout<<"**"<<str2num(n)<<endl;
if(str2num(n)>=l&&str2num(n)<=r){
cout<<'0'<<endl;
}
else if(str2num(n)<l||str2num(n)>r){
cout<<'2'<<endl;
}
//cout<<"*****************"<<endl;
}
}
/*
-3 3 4
100000000000000000000
0
00
-0
*/
过样例如下:
————————————————————分割线————————————————————————————————
知道问题出在哪了,我少判断一个条件,当输入仅一个“-”的时候也是不合法的
需要添加条件
if(n.size()==1){
if(n[0]=='-'){
cout<<'1'<<endl;
continue;
}
}
完整代码如下,但还有一个样例不过:
#include<iostream>
#include<cstdio>
#include <sstream>
#include <string>
using namespace std;
double str2num(string s){
double num;
stringstream ss(s);
ss>>num;
return num;
}
int main(){
double l,r,T;
cin>>l>>r>>T;
getchar();
for(int i=0;i<T;i++){
string n;
getline(cin,n);
if(n.size()==1){
if(n[0]=='-'){
cout<<'1'<<endl;
continue;
}
}
if(n.size()>=2){
if(n[0]=='0'){
cout<<'1'<<endl;
continue;
}else if(n[0]=='-'&&n[1]=='0'){
cout<<'1'<<endl;
continue;
}
}
if(str2num(n)>=l&&str2num(n)<=r){
cout<<'0'<<endl;
}
else if(str2num(n)<l||str2num(n)>r){
cout<<'2'<<endl;
}
}
}
/*
-3 3 4
100000000000000000000
0
00
-0
*/