CSP 202104-3 large scale simulation

Posted by spookztar on Fri, 10 Sep 2021 03:29:07 +0200

3 DHCP server

Because it is a big simulation, the topic is smelly, long and a little windy. To solve this problem, we should understand the meaning of the topic and write according to the requirements of the topic.

meaning of the title


Format of DHCP data message:

<Sending host> <Receiving host> <Message type> <IP address> <Expiration time>
 string    string     DIS
              *       OFR
                      REQ
                      ACK
                      NAK


Round 1

The code can be carried out step by step according to the detailed requirements given in the title, but some details need to be paid attention to, such as the relationship between conditions, whether to use and or.

The problem mainly occurs in this place: out gives the expiration time, so it is necessary to judge whether the expiration time exceeds the upper and lower limits

Note: in the 13th and 14th messages in the example explanation, e attempts to request an address. At this time, there is no address in the "unassigned" state in the address pool, but the state of address 2 previously assigned to b is "expired", so the address is reassigned to E. You can find that you forgot to deal with the expired address pool.

According to:

Before processing each command, handle the expired IP:

Wait for a while!!! The expiration time here should be IP [i]. Out < = t, not just =!!! If you don't find it, it will take a long time to debug??? What are you writing??? The most important thing in big simulation is the details!!! Be careful!!!

Round 2

After the above modifications, good results can be obtained basically. The following results are basically correct, but the last command can not be read and processed???

At this time, the score is only 40 points, so why did it terminate in advance???

Ah, fool, let you mess with break,

Because there is a break here, you just came here with your 15th command... And then break out the cycle of reading the command

Poof, only 60 points after correcting this bug... The sample can pass, but there must be other details not considered!!!

Round 3

Poof... Spit blood on your face

Here, here
debug de for so long... Didn't you find that it should be ip[j].own==send... It was written before = = receive, Old Swan... If it weren't for the right algorithm process, you wouldn't be able to find it?

I'm still too careless

Complete code

//#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=1e4+5;
struct node{
    int state;// 0 not allocated 1 to be allocated 2 occupied 3 expired
    int out;//Expiration time
    string own;//Occupier
}ip[maxn];
int main()
{
    int N,tdef,tmax,tmin,n;
    string H;
    cin>>N>>tdef>>tmax>>tmin>>H;
    for(int i=1;i<=N;i++)
    {
        ip[i].state=0;
        ip[i].out=0;
        ip[i].own="";
    } 
    cin>>n;
    for(int k=0;k<n;k++) 
    {   
        string send,receive,type;
        int address,t,out;
        //< message receiving time > < sending host > < receiving host > < message type > < IP address > < expiration time >
        cin>>t>>send>>receive>>type>>address>>out;
        //cout<<"y  "<<t<<endl;
        //cout<<"i "<<t<<" "<<send<<" "<<receive<<" "<<type<<" "<<address<<" "<<out<<endl;
        //cout<<"-!-"<<endl;
        //cout<<type<<endl;
        for(int i=1;i<=N;i++)//Traverse all IP addresses
        {
            if(ip[i].state==1&&ip[i].out<=t) //If the expiration time is earlier than the current time
            {
                ip[i].state=0;
                ip[i].own="";
                ip[i].out=0;

            }else if(ip[i].state==2&&ip[i].out<=t)
            {
                ip[i].state=3;
                ip[i].out=0;
            }else if(ip[i].state==3||ip[i].state==0)
            {
                ip[i].out=0;
            }
        }

        if((receive!=H&&receive!="*")&&type!="REQ") // Similarly, it should be & & and it was misplaced before! This should be judged first
            continue;
        
        //That's ok
        if(type!="REQ"&&type!="DIS") //How can you use it here? If the first condition is satisfied, even DIS will continue
            continue;
        //if(type=="REQ"||type=="DIS")
        //{ 
        if((receive=="*"&&type!="DIS")||(receive==H&&type=="DIS"))
            continue;
        
        if(type=="DIS")
        {
            int rip=-1;
            for(int j=1;j<=N;j++)
            {
                if(ip[j].state&&ip[j].own==send) // As long as it is not 0 unassigned, there will be occupiers
                {
                    rip=j;
                    break;
                }    
            }
            if(rip==-1) // If not, select the smallest IP address in unassigned status;
            {
                for(int j=1;j<=N;j++)
                {
                    if(!ip[j].state)
                    {
                        rip=j;
                        break;
                    }
                }
            }
            if(rip==-1) // If not, select the IP address whose minimum status is expired;
            {
                for(int j=1;j<=N;j++)
                {
                    if(ip[j].state==3)
                    {
                        rip=j;
                        break;
                    }
                }
            }
            if(rip!=-1) // Available ip found, continue processing
            {
                ip[rip].state=1;
                ip[rip].own=send;
                if(out==0)
                    ip[rip].out=t+tdef;
                else if(out-t>=tmax)
                    ip[rip].out=t+tmax;
                else if(out-t<=tmin)
                    ip[rip].out=t+tmin;
                else 
                    ip[rip].out=out;
                cout<<H<<" "<<send<<" OFR "<<rip<<" "<<ip[rip].out<<endl;
            }
            //if(rip==-1)
            //cout<<"not enough"<<endl;
        }else if(type=="REQ")
        {
            if(receive!=H) //No response will be sent to non local servers
            {
                for(int j=1;j<=N;j++)
                {
                    if(ip[j].own==send&&ip[j].state==1)
                    {
                        ip[j].state=0;
                        ip[j].own="";
                        ip[j].out=0;
                    }
                }
            }else //Note that the second half should be wrapped in else 
            {
                //if(!(address>=1&&address<=N&&ip[address].own==send))
                if(address<1||address>N||ip[address].own!=send)
                {
                    cout<<H<<" "<<send<<" NAK "<<address<<" 0"<<endl;
                }else{
                    ip[address].state=2;
                    if(out==0)
                        ip[address].out=t+tdef;
                    else if(out-t>tmax) // ??? Your brain watts, out-t is the effective time, and out gives the expiration time
                        ip[address].out=t+tmax;
                    else if(out-t<tmin)
                        ip[address].out=t+tmin;
                    else
                        ip[address].out=out;
                    cout<<H<<" "<<send<<" ACK "<<address<<" "<<ip[address].out<<endl;
                }  
            }
        }
        //}
    }
    //cout<<"out"<<endl;
    return 0;
}

summary

  large scale simulation requires patience and care. In fact, it's not difficult, but if you don't pay attention, the probability of writing a bug will be high, just like the stupid thing I did above... 2333
   in fact, you can start from the implementation details without looking at the principle part. It's useless 2333, but of course you need to know the working principle of DHCP... Of course, you can also write the process code step by step according to the details.
  finally, the details!!!

Topics: Algorithm CCF-CSP