DHCP服务器csp

1.解题思路

按照流程模拟,主要考虑ip地址的状态与分配情况,为了简单我直接暴力枚举了,即对每一次输入,首先对ip地址进行更新,(主要针对待分配情况和占用情况)再判断输入是否合法,合法再分为DIS和REQ两种情况进行讨论,对于DIS报文,直接遍历N个ip地址,找出符合条件的ip,没有则不分配,否则修改该ip地址的状态(0--未分配 1--待分配 2--占用 3--过期)、占用者和过期时间,输出相应OFR报文;对于REQ报文,需判断接收者是否为主机,ip地址是否合法,以及输入中的ip的占用者是否为发送者,再针对各种情况进行处理。

离大谱,居然要考虑ip地址不合法的情况,否则只能得70分。。。请务必加上

if(ip<1||ip>N)
				{
					cout<<H<<" "<<send<<" "<<"NAK"<<" "<<ip<<" "<<0<<endl;
					continue;
				} 

2.满分代码

#include<iostream>
using namespace std;
const int M=1e4+6;
int N,n,ip;
long long tdef,tmax,tmin,t,T;
string H;
struct IP{
	int flag;//0--未分配 1--待分配 2--占用 3--过期
	string owner;//占用者
	long long t;//过期时间 
}address[M];
bool islegal(string receive,string type)
{
	if(type!="DIS"&&type!="REQ")return false;
	if(receive==H || receive=="*")
	{
		if((receive=="*")&&(type!="DIS"))return false;
		if((receive==H)&&(type=="DIS"))return false;
	}
	else
	{
		if(type!="REQ")return false; 
	}
	return true;
}
void deleteovertime(long long t)
{
	for(int i=1;i<=N;i++)
	{
		if(address[i].t<=t)
		{
			if(address[i].flag==1)
			{
				address[i].flag=0;
				address[i].owner="";
				address[i].t=0;
			}
			else if(address[i].flag==2)
			{
				address[i].flag=3;
				address[i].t=0;
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	string send,receive,type;
	cin>>N>>tdef>>tmax>>tmin>>H;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>t;
		cin>>send>>receive>>type>>ip>>T;
		deleteovertime(t);
		if(islegal(receive,type))
		{
			if(type=="DIS")
			{
				int x=0;
				for(int i=1;i<=N;i++)
				{
					if(address[i].owner==send)
					{
						x=i;
						break;
					}
				}
				if(x==0)
				{
					for(int i=1;i<=N;i++)
					{
						if(address[i].flag==0)
						{
							x=i;
							break;
						}
					}
					if(x==0)
					{
						for(int i=1;i<=N;i++)
						{
							if(address[i].flag==3)
							{
								x=i;
								break;
							}
						}
						if(x==0)continue;
					}
				}
				if(x==0)continue;
				address[x].flag=1;
				address[x].owner=send;
				if(T==0)T=t+tdef;
				else
				{
					long long tmp1=t+tmax;
					long long tmp2=t+tmin;
					if(T<tmp2)T=tmp2;
					else if(T>tmp1)T=tmp1;
				}
				address[x].t=T;
				cout<<H<<" "<<send<<" "<<"OFR"<<" "<<x<<" "<<T<<endl;
			}
			else if(type=="REQ")
			{
				if(receive!=H)
				{
					for(int i=1;i<=N;i++)
					{
						if(address[i].owner==send)
						{
							if(address[i].flag==1)
							{
								address[i].flag=0;
								address[i].owner="";
								address[i].t=0;
							}
						}
					}
					continue;
				}
				if(ip<1||ip>N)
				{
					cout<<H<<" "<<send<<" "<<"NAK"<<" "<<ip<<" "<<0<<endl;
					continue;
				} 
				if(address[ip].owner!=send)
				{
					cout<<H<<" "<<send<<" "<<"NAK"<<" "<<ip<<" "<<0<<endl;
					continue;
				}
				else
				{
					address[ip].flag=2;
					if(T==0)T=t+tdef;
					else
					{
						long long tmp1=t+tmax;
						long long tmp2=t+tmin;
						if(T<tmp2)T=tmp2;
						else if(T>tmp1)T=tmp1;
					}
					address[ip].t=T;
					cout<<H<<" "<<send<<" "<<"ACK"<<" "<<ip<<" "<<T<<endl;
				}
			}
		}
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值