洛谷 P7911 [CSP-J 2021]网络连接(Network) 题解

P7911 [CSP-J 2021]网络连接(Network) 题解

题目评价:

一道普及组水题~

主要考验对STL String、Map与sscanf的运用

话不多说,放出代码,边看边讲

如果不想登陆就想复制代码, 请来我的洛谷博客:P7911题解 - SkyWave - 洛谷博客​​​​​​​

代码:

//
//  main.cpp
//  P7911 [CSP-J 2021] 网络连接
//
//  Created by SkyWave Sun on 2022/9/1.
//

#include <iostream>
#include <map>//STL map所在的头文件
using namespace std;
map<string, unsigned short> pool;//定义一个把string作为下标,类型为unsigned short的map
bool check(const string &str) {
    int a,b,c,d,port;
    if (sscanf(str.c_str()/*将string转换成char*/, "%d.%d.%d.%d:%d",&a,&b,&c,&d,&port) != 5/*sscanf返回按格式读取成功的参数,如果不是5个说明没有按照格式读取*/) {
        return false;
    }
    //sscanf用法:sscanf(从哪个字符串读取,读取格式,参数列表)
    //除了需要指定从哪个字符串读取,其他与scanf无异,包括返回值。
    //scanf与sscanf区别:
    //scanf:从stdin(标准输入)读取
    //sscanf:从C字符串(char数组)读取
    if (a < 0 || a > 255 || b < 0 || b > 255 || c < 0 || c > 255 || d < 0 || d > 255 || port < 0 || port > 65535) {
        return false;
    }
    //按照题目模拟判断即可
    string ip;
    ip += to_string(a);//to_string是C++11里在string头文件中新加入的函数,可以将任意类型转换为string类型
    ip += '.';
    ip += to_string(b);
    ip += '.';
    ip += to_string(c);
    ip += '.';
    ip += to_string(d);
    ip += ':';
    ip += to_string(port);
    //这一部分将a,b,c,d,port给组装成string
    if (ip.length() != str.length()) {//这里利用了int的特性,如果有前导0会自动忽略,所以如果有前导0的话这两个字符串的长度是不一样的
        return false;
    }
    return true;
    //这一部分可以简写成return ip.length() == str.length(),更加快捷
}
int main(int argc, const char * argv[]) {
    int n;
    scanf("%d",&n);
    for (int i = 1; i<=n; ++i) {//从1开始是为了顺便记录每个服务器的序号
        string method;
        string ip;
        cin>>method>>ip;
        if (!check(ip)) {
            printf("ERR\n");
            continue;
        }else {
            switch (method.at(0)/*method.at(0)也就是method[0],这是我的一个小癖好,因为method.at(0)可以捕获越界*/) {
                case 'S'://如果是服务器
                    if (!pool[ip]/*如果ip的对应位为0就说明没有被放在池子中*/) {
                        printf("OK\n");
                        pool[ip] = i;//pool[ip]就可以完成对ip为下标的map的访问,将它记录成i,也就是这个ip被第i台服务器所使用
                    }else {
                        printf("FAIL\n");//ip地址已经被其他服务器用过,冲突
                    }
                    break;
                case 'C'://如果是客户端
                    if (pool[ip]) {//这里代表如果pool[ip]不为0,也就是被使用过
                        printf("%d\n",pool[ip]);//就输出使用这个ip的服务器
                    }else {//如果没有服务器使用该ip
                        printf("FAIL\n");
                    }
                    break;
                default:
                    break;
            }
        }
    }
    return 0;
}

知识点总结:

1.Map

Map是一个可以把非正整数类型作为下标的“另类数组”,在这一题可以将ip地址作为下标,很方便的找出每个ip对应的序号。

定义Map的方式为map<数组下标类型,数组储存值的类型> Map名称。

Map可以用map.insert(pair<下标类型, 储存值类型>(下标, 值))插入,

也可以直接地实用map[下标] = 值插入。

2.sscanf

sscanf是一个从C字符串(char数组)按特定格式读取的类型,一共有三个参数。

sscanf(C字符串(char数组),格式,参数列表);

sscanf与scanf除了输入对象不同,其他特性均相同。

特别的,如果想用sscanf对C++string对象进行读取,需使用string::c_str()。

​​​​​​​3.to_string

to_string函数可以将任意类型转换为string类型,在C++11标准及以上可以使用。

完结撒花!

看不懂的请在评论区留言~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值