洛谷:P7911
OJ: 4972
不判断ip合法性,能得55分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <iostream> #include <map> using namespace std; int n; map<string,int> server; //判断 ip合法性 bool check(string ip){ return true; } int main(){ cin>>n; string s,t; for (int i = 1; i <=n; i++){ cin>>s>>t; if(!check(t)){ cout<<"ERR"<<endl; continue; } if(s=="Server"){ if(server[t]==0){ server[t]=i; cout<<"OK"<<endl; }else{ cout<<"FAIL"<<endl; } }else{ if(server[t]>0){ cout<<server[t]<<endl; }else{ cout<<"FAIL"<<endl; } } } } |
满分方法一:代码详细解读:
n
:表示要处理的计算机的数量。server
:一个 map
,用于存储成功建立连接的服务机地址与其编号的映射关系。check
函数:用于验证地址串是否符合 IP 地址的规范格式。
.
和 :
出现的次数,同时提取 IP 地址中的 a,b,c,d 及端口号 e。true
,否则返回 false
。check
函数检查地址串是否合法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /**************************************************************** * Description: 2021年普及组复赛第三题 网络连接 * Author: Alex Li * Date: 2023-10-16 10:33:25 * LastEditTime: 2024-10-18 11:22:47 ****************************************************************/ #include <iostream> #include <map> using namespace std; int n; // 代表计算机的总数 map<string, int> server; // 用于记录服务机已成功建立连接的地址及其编号 // 判断 IP 地址是否符合规范的函数 bool check(string s) { int len = s.length(); // 获取地址字符串的长度 long long tmp = 0; // 临时变量,用于提取数字 int cnt1 = 0, cnt2 = 0, cnt3 = 0; // cnt1 统计 '.' 的个数,cnt2 统计 ':' 的个数,cnt3 统计数字的个数 for (int i = 0; i < len; i++) { // 如果当前位置为第一个字符或前一个字符为 '.' 或 ':' 且当前位置是数字,则增加数字计数器 if ((i == 0 || (s[i-1] == '.' || s[i-1] == ':')) && s[i] >= '0' && s[i] <= '9') cnt3++; // 如果当前位置是 '.' 或 ':' if (s[i] == '.' || s[i] == ':') { if (s[i] == '.') cnt1++; // '.' 出现,增加计数器 else if (s[i] == ':') cnt2++; // ':' 出现,增加计数器 // 检查 '.' 和 ':' 出现的顺序是否符合规范 if (cnt1 < 3 && cnt2 > 0) return false; // 如果 ':' 出现在第三个 '.' 之前,不符合规范 if (cnt3 == 0) return false; // 如果 '.' 或 ':' 出现在没有数字的情况下,不符合规范 // 检查数字部分 a,b,c,d 是否在合法范围内 if (0 <= tmp && tmp <= 255) { tmp = 0; // 数字合法,重置 tmp 继续处理下一个数字 continue; } else { return false; // 数字不合法,返回 false } } // 如果出现了非数字字符,返回 false else if (s[i] < '0' || s[i] > '9') return false; // 检查是否有前导 0(前导 0 在 IP 地址中是不允许的) if (i > 0 && !tmp && s[i-1] == '0') return false; // 提取当前数字并存入 tmp tmp = tmp * 10 + s[i] - '0'; } // 检查 '.' 出现的次数是否为 3,':' 出现的次数是否为 1,以及数字部分是否有 5 个 if (cnt1 != 3 || cnt2 != 1 || cnt3 != 5) return false; // 检查端口号(e)是否在合法范围内(0 到 65535) if (0 <= tmp && tmp <= 65535) return true; else return false; } int main() { cin >> n; // 读取计算机数量 string s, t; // s 用于存储操作类型(Server 或 Client),t 用于存储地址串 for (int i = 1; i <= n; i++) { cin >> s >> t; // 读取每台计算机的操作类型和地址串 // 检查地址串是否合法 if (!check(t)) { cout << "ERR" << endl; // 如果地址不合法,输出 "ERR" continue; // 继续处理下一台计算机 } // 如果是服务机 if (s == "Server") { // 检查该地址是否已经有其他服务机使用 if (server[t] == 0) { // 如果该地址未被使用,成功建立连接并记录 server[t] = i; cout << "OK" << endl; // 输出 "OK" 表示成功建立连接 } else { // 如果地址已被使用,输出 "FAIL" cout << "FAIL" << endl; } } else { // 如果是客户机 // 检查是否有服务机使用该地址 if (server[t] > 0) { // 如果找到匹配的服务机,输出该服务机的编号 cout << server[t] << endl; } else { // 如果未找到匹配的服务机,输出 "FAIL" cout << "FAIL" << endl; } } } } |
满分方法二:调用了sscanf和sprintf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <iostream> #include <map> #include <stdio.h> using namespace std; int n; map<string,int> server; //判断 ip合法性 bool check(string ip){ int t[6]={0,-1,-1,-1,-1,-1}; int cnt=sscanf(ip.c_str(),"%d.%d.%d.%d:%d",&t[1],&t[2],&t[3],&t[4],&t[5]); if(cnt!=5)return false; for (int i =1; i <=4; i++){ if(t[i]<0||t[i]>255)return false; } if(t[5]<0||t[5]>65535)return false; char now[30]; sprintf(now,"%d.%d.%d.%d:%d",t[1],t[2],t[3],t[4],t[5]); if(string(now)!=ip) return false; return true; } int main(){ cin>>n; string s,t; for (int i = 1; i <=n; i++){ cin>>s>>t; if(!check(t)){ cout<<"ERR"<<endl; continue; } if(s=="Server"){ if(server[t]==0){ server[t]=i; cout<<"OK"<<endl; }else{ cout<<"FAIL"<<endl; } }else{ if(server[t]>0){ cout<<server[t]<<endl; }else{ cout<<"FAIL"<<endl; } } } } |