CCF-CSP 2021-4-3 DHCP服务器 100分题解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片在这里插入图片描述
描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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.本题虽然题目长,但是确实是一道特别特别暴力的模拟题,基本没有需要构思特殊逻辑和数据结构的地方,只要按部就班地写就好了

提交记录

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值