📜  门|门模拟 2017 |问题 9(1)

📅  最后修改于: 2023-12-03 14:58:37.907000             🧑  作者: Mango

门|门模拟 2017 | 问题 9

本题是2017年门|门模拟比赛的第9题。该题目要求我们模拟门的开启和关闭以及门后的状态变化。该题采用的是C++编程语言。下面将对该题目的具体内容和解题思路进行介绍。

题目描述
  • 输入门的数量n和m个事件内容和事件参数。
  • 事件内容包括“open”“close”和“query”。
  • 事件参数为一个整数,对于事件“open”和“close”表示要打开或关闭的门号,对于事件“query”表示需要查询门状态变量的门号。
  • 对于一个门,当离开某个人最近的开门事件之后,该门的状态会变为open。当离开某个人最近的关门事件之后,该门的状态会变为closed。初始状态为closed。
解题思路

本题考查的主要是对模拟的掌握程度。对于该题目,我们需要按顺序处理每个事件,并对门的状态进行相应操作。具体步骤如下:

  1. 读入门的数量n和事件次数m

  2. 定义一个队列,记录每个门最近的关门事件(如果最近的事件是开门,则将事件丢弃)

  3. 对于每个事件,按照如下方式处理:

    • 对于事件“open”和“close”,获取门号和时间,计算该门离最近的关门事件距离(如果最近的事件是开门,则将事件丢弃)。如果该门当前状态为closed,将该事件添加到队列中;如果该门状态为open,并且该事件距离最近的关门事件的距离小于等于该事件的距离,不进行任何操作;否则,将该事件添加到队列中,并将该门状态设置为closed(即需要反转门的状态)。
    • 对于事件“query”,输出该门的状态。
代码片段

以下是对该题目的一个简单实现代码:

#include<bits/stdc++.h>
using namespace std;
const int N=100005;

int n,m;
int last_close[N];//记录离关闭时间最近的关门事件

int main()
{
    scanf("%d%d",&n,&m);
    memset(last_close,-1,sizeof(last_close));

    for(int i=1;i<=m;i++)
    {
        string op;
        cin>>op;

        if(op=="open")
        {
            int doorid,time;
            scanf("%d%d",&doorid,&time);

            if(last_close[doorid]==-1 || time-last_close[doorid]>10)//需要打开
                printf("Opened by %d\n",time);
            else//不需要打开
            {
                printf("Detected %d\n",time);
                last_close[doorid]=-1;//弃掉这次关门事件,不要记录
            }
        }
        else if(op=="close")
        {
            int doorid,time;
            scanf("%d%d",&doorid,&time);

            if(last_close[doorid]==-1 || time-last_close[doorid]>10)//需要关门
            {
                printf("Closed by %d\n",time);
                last_close[doorid]=time;//更新最近关门事件
            }
            else//不需要关门
                printf("Invalid\n");
        }
        else//query
        {
            int doorid;
            scanf("%d",&doorid);

            if(last_close[doorid]==-1 || last_close[doorid]==0 || m-last_close[doorid]>10)
                printf("Closed\n");//最近的关门事件早于开门事件或未曾关过门,门是关闭的
            else
                printf("Opened\n");//最近的关门事件是在开门事件之后,门是开启的
        }
    }
    return 0;
}

以上代码针对该题目中每个事件进行了不同的处理,展示了不同的情况下应该输出的信息。该代码片段返回的是C++代码,需要在Markdown文档中标识。