洛谷P5238 整数校验器

看到没有边读入边处理的,我来水一发

我们要看一下有那些情况是格式不合法的

  1. 单独的负号

  2. -0(后面可以有其他数字)

  3. 0 +(后面一些数字)

我们用快速读入的方法

读取字符进行处理

还有可能超出范围的

考虑到l和r不超过20位

于是我们开一个cnt变量记录位数

如果cnt>20明显超出边界

否则按照快速读入的方法算出读入的数字

然后进行判断

要开一个至少能存储20位的整数类型,我使用了__int128

#include <bits/stdc++.h>

#define int long long
#define ll __int128

using namespace std;

int l, r;

int read() {
    char c = getchar();
    ll tmp = 0, f = 1, flag = 0, first_zero = 0, cnt = 0;
    while(!isdigit(c)) { // 读入特殊字符
        if(c == '-') { 
            if(f == -1) {
                flag = 1; // 判断两个负号连在一起的情况(然而并没有)
            }
            f = -f;
        } else {
            if(c != '\n')flag = 1; // 出现了特殊情况(然而并不会有)
        }
        c = getchar();
        if(c == '\n') return 1; // 单独的负号
    }
    // cout << flag << endl;
    while(isdigit(c)) {
        cnt++;
        if(cnt == 1 && c == '0') first_zero = 1; // 第一次出现的数是0
        if(cnt == 2 && first_zero) flag = 1; // 第一次出现的数是0,并且后面还有数,显然不合法
        tmp = (tmp << 1) + (tmp << 3) + c - 48;
        c = getchar();
    }
    if(tmp == 0 && f == -1 && cnt == 1) return 1; // 如果是-0,明显不合法
    if(flag) return flag;
    tmp *= f;
    if(((cnt <= 20 && (tmp < l || tmp > r)) || cnt > 20) && !flag) return 2; // 超出边界
    else return flag;
}

signed main() {
    int t;
    cin >> l >> r >> t;
    while(t--) {
        cout << read() << endl;
    }
    return 0;
} // qwq

猜你喜欢

转载自www.cnblogs.com/iycc/p/10468096.html