100分题解
/*DHCP服务器*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int status, out_date;//地址编号 地址状态 过期时间
string user;//占用者
node():user(""), out_date(0), status(0) {}
//node(int i_):i(i_),user(""),out_date(0),status(0) {}
};
//0:未分配 1:待分配 2:占用 3:过期
vector<node>vec;
int N, T_def, T_max, T_min;//地址池大小 默认过期时间 过期时间上限 下限
string H;//本机名称
int getnum(string str)
{
int val = 0;
for (int i = 0; i < str.length(); i++) {
val = val * 10 + str[i] - '0';
}
return val;
}
bool islegal(string receive,string type)
{
if (receive == H || receive == "*") {
if (type != "DIS" && type != "REQ") return false;
else {
if (receive == "*" && type == "REQ") return false;
else if (receive == H && type == "DIS") return false;
else return true;
}
}
else {
if (type == "REQ") return true;
else return false;
}
}
void dis_pro(int ti,string sender,int expected_date)
{
int ip = -1;
for (int i = 1; i <= N; i++) {
if (vec[i].user == sender) {
ip = i;
break;
}
}
if (ip == -1) {
for (int i = 1; i <= N; i++) {
if (vec[i].status == 0) {
ip = i;
break;
}
}
}
if (ip == -1) {
for (int i = 1; i <= N; i++) {
if (vec[i].status == 3) {
ip = i;
break;
}
}
}
if (ip != -1) {
vec[ip].status = 1;//0->1
vec[ip].user = sender;
if (expected_date == 0) {
//date 报文中的过期时刻
vec[ip].out_date = ti + T_def;
}else {
int span = expected_date - ti;
span = min(T_max, span);
span = max(T_min, span);
vec[ip].out_date = ti + span;
}
//发送主机 接受主机 报文类型 IP地址 过期时刻
cout << H << " " << sender << " " << "OFR" << " " << ip << " " << vec[ip].out_date << endl;
}
}
void req_pro(int ti,int ip,string sender,string receiver,int expected_date)
{
if (receiver == H) {//接收主机是本机
if (ip <= N && ip >= 1 && vec[ip].user==sender) {
vec[ip].status = 2;
if (expected_date == 0) {
//date 报文中的过期时刻
vec[ip].out_date = ti + T_def;
}
else {
int span = expected_date - ti;
span = min(T_max, span);
span = max(T_min, span);
vec[ip].out_date = ti + span;
}
cout << H << " " << sender << " " << "ACK" << " " << ip << " " << vec[ip].out_date << endl;
}else {
cout << H << " " << sender << " " << "NAK" << " " << ip << " " << 0 << endl;
}
}
else {
for (int i = 1; i <= N; i++) {
if (vec[i].user == sender && vec[i].status==1) {
vec[i].status = 0;
vec[i].user = "";
vec[i].out_date = 0;
}
}
}
}
void modify(int time)
{
for (int i = 1; i <= N; i++) {
if (vec[i].status == 1) {//待分配
if (time >= vec[i].out_date) {
vec[i].status = 0;
vec[i].user = "";
vec[i].out_date = 0;
}
}else if (vec[i].status == 2) {//占用
if (time >= vec[i].out_date) {
vec[i].status = 3;
vec[i].out_date = 0;
}
}
}
}
int main()
{
cin >> N >> T_def >> T_max >> T_min >> H;
vec.push_back(node());
for (int i = 1; i <= N; ++i) {//初始化地址池
vec.push_back(node());
}
int n;//n个报文
cin >> n;
//发送主机 接受主机 报文类型 IP地址 过期时刻
string time, sender, receiver, type, IP, out_of_date;
for (int i = 0; i < n; i++) {
cin >> time >> sender >> receiver >> type >> IP >> out_of_date;
int ti = getnum(time);
int out_date = getnum(out_of_date);
int ip = getnum(IP);
if (!islegal(receiver, type)) {
continue;
}
modify(ti);
if (type == "DIS") {
dis_pro(ti, sender, out_date);
}else {
req_pro(ti,ip,sender,receiver,out_date);
}
}
return 0;
}
总结
1.本题信息量庞杂,需要有极强的问题提取和分析能力,否则根本无法在短时间内写出。
2.在代码中第68行,我曾错误把待分配看成了未分配,导致只能得10分,仅仅把代表未分配状态的0改成代表待分配状态的1,就实现了10分到100分的跨越。
3.本题虽然题目长,但是确实是一道特别特别暴力的模拟题,基本没有需要构思特殊逻辑和数据结构的地方,只要按部就班地写就好了