云计算百科
云计算领域专业知识百科平台

CSP-J 2021 网络连接 题解

题意梳理

核心规则

  • 合法地址格式强制要求:严格形如 a.b.c:d:e 拆分结构是a.b.c.d:e,必须恰好 3 个. ,1 个: ;
    数值范围:0<=a,b,c,d<=255,0<=e<=65535
    禁止多余前导零(如099、01非法,单独0合法)

  • Server 逻辑
    地址非法 → 输出ERR
    地址合法且未被之前 Server 占用 → 存入map<地址串,编号>,输出OK
    地址合法但已存在同地址 Server → 输出FAIL

  • Server 逻辑
    地址非法 → 输出ERR
    地址合法且未被之前 Server 占用 → 存入map<地址串,编号>,输出OK
    地址合法但已存在同地址 Server → 输出FAIL

  • 地址处理
    普通写法要手动分割字符串、逐段遍历判断前导零,代码冗长易错;
    此时可以用两次格式化函数一步到位:(绝对不是因为懒)
    sscanf按%d.%d.%d.%d:%d读取 5 个整数:
    若格式不对,读取数量≠5 直接判非法;顺便完成数值范围校验
    sprintf把读取到的合法整数重新格式化拼接成标准字符串:
    整数格式化自动去除前导零!比如原串192.168.001.1:80,读整数再拼接会变成192.168.1.1:80
    直接对比原字符串和重拼接后的字符串,不一致就说明原串有前导零,直接非法!

  • 完整AC代码

    #include <bits/stdc++.h>
    using namespace std;
    map<string,int> server;//地址与编号

    bool check(string s)
    {
    int cnt1=0,cnt2=0;
    for(int i=0;i<s.size();i++)
    {
    if(s[i]=='.') cnt1++;
    if(s[i]==':') cnt2++;
    }
    if(cnt1!=3||cnt2!=1) return false;
    int a,b,c,d,e;
    if(sscanf(s.c_str(),"%d.%d.%d.%d:%d",&a,&b,&c,&d,&e)!=5) return false;
    if(a<0||a>255||b<0||b>255||c<0||c>255||d<0||d>255||e<0||e>65535) return false;
    char buf[50];
    sprintf(buf,"%d.%d.%d.%d:%d",a,b,c,d,e);
    if(s!=string(buf)) return false;//检查前导0。
    return true;
    }

    int main()
    {
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    string op,ad;
    cin>>op>>ad;
    if(check(ad))
    {
    if(op=="Server")
    {
    if(server.count(ad))
    {
    cout<<"FAIL"<<endl;
    }
    else
    {
    server[ad]=i;
    cout<<"OK"<<endl;
    }
    }
    else
    {
    if(server.count(ad))
    {
    cout<<server[ad]<<endl;
    }
    else
    {
    cout<<"FAIL"<<endl;
    }
    }
    }
    else
    {
    cout<<"ERR"<<endl;
    }
    }
    return 0;
    }

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » CSP-J 2021 网络连接 题解
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!