最近两题状态不是很好,代码写的好长,丑陋,很嫌弃。
后面再好好重构吧。
#include<bits/stdc++.h>
using namespace std;
struct IP {
string holder;
int type;
int outTime;
};
struct Frame {
string sender,receiver,type;
int ipaddr,outTime;
};
struct DHCPServer {
string H;
int N,T_def,T_max,T_min;
set<int> unAllocated;//未分配 0
set<int> waitAllocated;//待分配 1
set<int> Allocated;//已经分配 2
set<int> timeOut;//过期 3
unordered_map<int, IP> ipPool;// address->IP
unordered_map<string, unordered_set<int>> holders;//holder->addresses
}server;
int n;
void solveDIS(Frame frame, int t) {
int addr = -1;
if (!server.holders[frame.sender].empty()) {//有
addr = *server.holders[frame.sender].begin();
if (server.ipPool[addr].type == 2) {
server.Allocated.erase(addr);
} else if (server.ipPool[addr].type == 3) {
server.timeOut.erase(addr);
}
} else {//没有
if (!server.unAllocated.empty()) {//待分配
addr = *server.unAllocated.begin();
server.unAllocated.erase(addr);
} else {//也没有待分配
if (!server.timeOut.empty()) {//过期
addr = *server.timeOut.begin();
server.timeOut.erase(addr);
server.holders[server.ipPool[addr].holder].erase(addr);
} else {//没有过期的
return;
}
}
server.holders[frame.sender].insert(addr);
}
int ot;
if (frame.outTime == 0) {
ot = t + server.T_def;
} else {
if (frame.outTime >= t + server.T_max) {
ot = t + server.T_max;
} else if (frame.outTime <= t + server.T_min) {
ot = t + server.T_min;
} else {
ot = frame.outTime;
}
}
server.ipPool[addr] = IP{frame.sender,1,ot};
server.waitAllocated.insert(addr);
//send offer
cout << server.H << " " << frame.sender << " " << "OFR " << addr << " " << ot << '\n';
}
void solveREQ(Frame frame, int t) {
if (frame.receiver != server.H) {
set<int>ear;
auto& ips = server.holders[frame.sender];
for (auto& ip: ips) {
if (server.waitAllocated.count(ip)) {
ear.insert(ip);
server.waitAllocated.erase(ip);
server.unAllocated.insert(ip);
server.ipPool[ip] = IP{"",0,0};
}
}
for (auto& ip:ear) {
server.holders[frame.sender].erase(ip);
}
return;
}
if (server.holders[frame.sender].count(frame.ipaddr)) {
int type = server.ipPool[frame.ipaddr].type;
if (type == 0) {
server.unAllocated.erase(frame.ipaddr);
} else if (type == 1) {
server.waitAllocated.erase(frame.ipaddr);
} else if (type == 3) {
server.timeOut.erase(frame.ipaddr);
}
server.Allocated.insert(frame.ipaddr);
int ot;
if (frame.outTime == 0) {
ot = t + server.T_def;
} else {
if (frame.outTime >= t + server.T_max) {
ot = t + server.T_max;
} else if (frame.outTime <= t + server.T_min) {
ot = t + server.T_min;
} else {
ot = frame.outTime;
}
}
server.ipPool[frame.ipaddr].outTime = ot;
server.ipPool[frame.ipaddr].type = 2;
server.ipPool[frame.ipaddr].holder = frame.sender;
//send Ack
cout << server.H << " " << frame.sender << " " << "ACK " << frame.ipaddr << " " << ot << '\n';
} else {
//send Nak
cout << server.H << " " << frame.sender << " " << "NAK " << frame.ipaddr << " " << 0 << '\n';
}
}
void update(int t) {
set<int> aux;
for (auto& ip: server.waitAllocated) {
if (server.ipPool[ip].outTime > 0 && server.ipPool[ip].outTime <= t) {
aux.insert(ip);
server.holders[server.ipPool[ip].holder].erase(ip);
server.ipPool[ip] = IP{"", 0, 0};
}
}
for (auto& ip:aux) {
server.waitAllocated.erase(ip);
server.unAllocated.insert(ip);
}
set<int> tmp;
for (auto& ip: server.Allocated) {
if (server.ipPool[ip].outTime > 0 && server.ipPool[ip].outTime <= t) {
tmp.insert(ip);
server.ipPool[ip].type = 3;
server.ipPool[ip].outTime = 0;
}
}
for (auto& ip:tmp) {
server.Allocated.erase(ip);//过期
server.timeOut.insert(ip);
}
}
void solve() {
int t; string sender,receiver,type;
int ipaddr,outTime;
cin >> t >> sender >> receiver >> type >> ipaddr >> outTime;
if (receiver != "*" && receiver != server.H) {
if (type != "REQ") {
return;
}
}
if (type != "DIS" && type != "REQ") {return;}
if ((receiver == "*" && type != "DIS") || (receiver == server.H && type == "DIS")) {return;}
update(t);
if (type == "DIS") {
solveDIS(Frame{sender,receiver,type,ipaddr,outTime},t);
} else {
solveREQ(Frame{sender,receiver,type,ipaddr,outTime},t);
}
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> server.N >> server.T_def >> server.T_max >> server.T_min >> server.H;
cin >> n;
for(int i = 1; i <= server.N; i++) {
server.unAllocated.insert(i);
}
for (int i = 0; i < n; i++) {
solve();
}
}