csp2021-04-3 DHCP服务器

大模拟,按照题目要求一步一步来。
考试时因为题意理解错了只拿了70分,以后一定要认真审题

我的做法是用结构体存每一个ip,每一次处理前都需要刷新一下所有IP的状态,如果有过期的需要注意:待分配而未占用的,要清空占用者;已占用的不用清空占用者。

#include<stdio.h>
#define MAX(x,y)  (((x)>(y))?(x):(y))
#define MIN(x,y)  (((x)<(y))?(x):(y))
#include<string.h>
const int MAXN=1e4+5;
typedef long long ll;
char zj[25];
char post[25],get[25],kind[20];
ll t,tmin,tmax,tdft;
ll address;
ll ot;
ll step,T;
ll maxn,nowtime;
struct st
{
	ll state;   	//0 未分配 1 待分配 2 占用 3 过期
	ll outtime;		//过期时间 
	char owner[25];
} ip[10005];
void brush()
{
	ll i;
	for( i=1; i<=maxn; i++)
		if(ip[i].outtime<=nowtime)
			{
				if(ip[i].state==2)
					ip[i].state=3;
				if(ip[i].state==1)
					{
						ip[i].state=0;
						strcpy(ip[i].owner,"");
					}
			}
}
ll checkusedip()
{
	ll i;
	for( i=1; i<=maxn; i++)
		if(strcmp(ip[i].owner,post)==0)
			return i;
	for( i=1; i<=maxn; i++)
		if(ip[i].state==0)
			return i;
	for( i=1; i<=maxn; i++)
		if(ip[i].state==3)
			return i;
	return 0;
}
int solve()
{
	brush();
	if(strcmp(get,zj)!=0&&strcmp(get,"*")!=0)
		{
			if(strcmp(kind,"REQ")!=0)
				return 0;
		}
	if(strcmp(kind,"DIS")!=0&&strcmp(kind,"REQ")!=0)
		return 0;
	if(strcmp(get,"*")==0&&strcmp(kind,"DIS")!=0)
		return 0;
	if(strcmp(get,zj)==0&&strcmp(kind,"DIS")==0)
		return 0;
	if(strcmp(kind,"DIS")==0)			//discover
		{
			ll f;
			f=checkusedip();
			if(!f) return 0;
			ip[f].state=1;
			strcpy(ip[f].owner,post);
			if(ot==0)
				{
					ip[f].outtime=nowtime+tdft;
				}
			else
				{
					ll newot=ot;
					newot=MAX(nowtime+tmin,newot);
					newot=MIN(nowtime+tmax,newot);
					ip[f].outtime=newot;
				}
			printf("%s %s OFR %lld %lld\n",zj,post,f,ip[f].outtime);
		}
	else if(strcmp(kind,"REQ")==0)		//request
		{
			if(strcmp(get,zj)!=0)
				{
					ll i;
					for(i=1; i<=maxn; i++)
						{
							if(strcmp(ip[i].owner,post)==0)
								{
									if(ip[i].state ==1) 
										{
											ip[i].state=0;
											strcpy(ip[i].owner,"");
											ip[i].outtime=0;
										}
								}
						}
					return 0;
				}
			if(address>maxn||strcmp(ip[address].owner,post)!=0)
				{
					printf("%s %s NAK %lld 0\n",zj,post,address);
					return 0;
				}
			if(ot==0)
				ip[address].outtime=nowtime+tdft;
			else
				{
					ll newot=ot;
					newot=MAX(nowtime+tmin,newot);
					newot=MIN(nowtime+tmax,newot);
					ip[address].outtime=newot;
				}
			ip[address].state=2;
			printf("%s %s %s %lld %lld\n",zj,post,"ACK",address,ip[address].outtime);
		}
	return 0;
}
int main()
{
	scanf("%lld%lld%lld%lld%s",&maxn,&tdft,&tmax,&tmin,zj);
	ll i;
	for(i=0; i<=maxn; i++)
		{
			ip[i].outtime=0;
			ip[i].state=0;
			strcpy(ip[i].owner,"");
		}
	scanf("%lld",&T);
	while(T--)
		{
			scanf("%lld%s%s%s%lld%lld",&nowtime,post,get,kind,&address,&ot);
			solve();
		}
	return 0;
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值