AcWing 3413. DHCP服务器
原题链接
中等
DHCP服务器
//#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
//地址池大小 N 默认过期时间 Tdef
//过期时间的上限和下限 Tmax、Tmin
//本机名称 H
int n, m, t_def, t_max, t_min;
string h;
struct ip
{
int state;//地址状态:0:未分配、1:待分配、2:占用、3:过期
int t;//过期时刻
string owner;//占用者
}ip[N];
void update_ips_state(int tc)
{
for(int i=1; i<=n; i++)
{
if(ip[i].t && ip[i].t <= tc)
{
if(ip[i].state == 1)
{
ip[i].state = 0;
ip[i].owner = "";
ip[i].t = 0;
}
else
{
ip[i].state = 3;
ip[i].t = 0;
}
}
}
}
int get_id_by_state(int state)
{
for(int i=1; i<=n; i++)
if(ip[i].state == state)
return i;
return 0;
}
int get_id_by_owner(string client)
{
for(int i=1; i<=n; i++)
if(ip[i].owner == client)
return i;
return 0;
}
int main()
{
cin>>n>>t_def>>t_max>>t_min>>h;
cin>>m;//收到了m个报文
while(m--)
{
int tc;
//<发送主机> <接收主机> <报文类型> <IP 地址> <过期时刻>
string client, server, type;
int id, te;
cin>> tc >> client >> server >> type >> id >> te;
if(server != "*" && server != h)
{
if(type != "REQ") continue;
}
if(type != "REQ" && type != "DIS") continue;
if((server == "*" && type != "DIS") || (server == h && type == "DIS")) continue;
update_ips_state(tc);
//处理 Discover 报文
if(type == "DIS")
{
//1
int k = get_id_by_owner(client);
if(!k) k = get_id_by_state(0);
if(!k) k = get_id_by_state(3);
if(!k) continue;
//2
ip[k].state = 1, ip[k].owner = client;
//3
if(!te) ip[k].t = tc + t_def;
else
{
int t = te - tc;
t = max(t, t_min);
t = min(t, t_max);
ip[k].t = t + tc;
}
//4
cout<<h<<" "<<client<<" "<<"OFR"<<" "<<k<<" "<<ip[k].t<<endl;
}
else if(type == "REQ")
{
//1
if(server != h)
{
for(int i=1; i<=n; i++)
{
if(ip[i].owner == client && ip[i].state == 1)
{
ip[i].state = 0;
ip[i].owner="";
ip[i].t = 0;
}
}
continue;
}
//2
if(!(id>=1 && id<=n && ip[id].owner==client))
{
cout<<h<<" "<<client<<" "<<"NAK"<<" "<<id<<" "<<0<<endl;
//continue;
}
else
{
//3
ip[id].state = 2;
//4
if(!te) ip[id].t = tc + t_def;
else
{
int t = te - tc;
t = max(t, t_min);
t = min(t, t_max);
ip[id].t = t + tc;
}
//5
cout<<h<<" "<<client<<" "<<"ACK"<<" "<<id<<" "<<ip[id].t<<endl;
}
}
}
return 0;
}