CSP 202104-3 DHCP服务器

最近两题状态不是很好,代码写的好长,丑陋,很嫌弃。

后面再好好重构吧。

#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();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值