AcWing 4088. 网络连接
原题链接
中等
作者:
nanyuyi
,
2024-10-04 20:57:08
,
所有人可见
,
阅读 1
#include<iostream>
#include<unordered_map>
using namespace std;
int idx;
unordered_map<string,int> f;
//哈希表,用来映射
//用map也可以,只是多一个log
bool check(string s){
int cnt=0,cnt2=0;
//记录点与冒号的数量
//可以用于查该字符串是否合法
int x=s.size();
for(int i=0;i<x;i++){
if(!isdigit(s[i])&&s[i]!=' '){
if(s[i]=='.'){
cnt++;
}else if(s[i]==':'){
cnt2++;
}
//计数
}
}
if(cnt!=3||cnt2!=1){
return 0;
}//判断是否合法
int siz=0,sum=-1;
/*
siz:当前数值的位数
sum:具体数值
*/
//sum=-1是因为两个非数字字符中间没有数字字符
//这样也是不合法的
int la=0;
/*
记录最后一个非数字字符出现的位置
用来确定是否到了最后一个数字
*/
for(int i=x-1;~i;i--){
if(!isdigit(s[i])){
la=i;
break;
}
}
/*
这样方便判断是否合法
(因为前4个数与最后一个数的合法范围不同)
*/
int fi=10;
//记录该数值的第一位数字
for(int i=0;i<x;i++){
if(sum>255&&i<=la){
return 0;
}
if(sum>65535){
return 0;
}
/*
因为每一个数值必定小于65536
这里我怕数值会爆掉(太大了),所以提前判断掉
(免得我后面死活调不出来)
*/
//根据数值判断是否合法
if(!isdigit(s[i])){
if(sum==-1){
return 0;
}//中间没有数
//下面处理前导零问题
if(sum==0&&siz>1){
return 0;//数值为0但长度大于1
}else if(sum>0&&!fi){
return 0;//数值不为0但是以0开头
}
//判断对应字符是否正确
if(i==la&&s[i]!=':'){
return 0;
}else if(i!=la&&s[i]!='.'){
return 0;
}
siz=0,sum=-1,fi=10;
//初始化
continue;
}
if(fi==10){
fi=s[i]-'0';
}//找到该数值的第一个数字
if(sum==-1){
sum=s[i]-'0';
}else{
sum=sum*10+(s[i]-'0');
}//算该数值具体是多少
siz++;//数值位数加1,方便上面的判断
}
//以下是单独处理最后一个数
if(sum<0){
return 0;
}
if(sum>65535||(sum==0&&siz>1)||(sum>0&&fi==0)){
return 0;
}
//如果以上条件均满足,即合法
return 1;
}
int main(){
int t;
cin>>t;
getchar();
while(t--){
idx++;
string s,t;
cin>>s>>t;
/*
这里为方便,分两个部分读入
s:是服务器还是客户机
t:地址
*/
if(!check(t)){
puts("ERR");
continue;//不合法即直接ERR
}
//以下是分类讨论
if(s[0]=='S'){
if(f[t]){
puts("FAIL");
//已经出现过,即无法链接
}else{
puts("OK");
f[t]=idx;//记录该地址对应服务器的编号
}
}else{
if(!f[t]){
puts("FAIL");
//没有该服务器
}else{
printf("%d\n",f[t]);//有,输出服务器编号
}
}
}
//完结撒花!!!
return 0;
}