2 条题解

  • 2
    @ 2026-8-11 10:21:41

    我认为题解并没有学到STL的精髓......

    1:初始思路

    看到题目,我们可以知道其实这个地道就是一条链,中间断了两边就无法相通

    那题目让我们输出每一个被围堵的士兵能够到达的房子有几个,就是我们要从小到大维护被摧毁的房子编号,每两个编号间的差再1-1就是答案,因为边界不能走

    这时,我们能想到setset的两个特殊性质之一:自动排序,刚好满足我们的维护需求

    2:完成题目

    33个任务的输出答案已经出来了,就是在QQ xx时找到在setset中比xx大的第一个和比xx小的最后一个,位置之差1-1即为答案

    最后只剩完成前面的任务了

    11个任务也迎刃而解,只需insert(x)insert(x)即可

    那就只差第22个任务了,它让我们将上一个加入setset的数eraseerase掉,这时难道想不到用stackstack后进先出的性质吗?!

    吐槽:题解还非要开一个数组来从尾到头地记录,stackstack直接pushpush,需要时取出stackstacktop()top()不就行了嘛,由此可见题解的STLSTL并不能熟练运用.....

    然后实现即可AC

    #include<bits/stdc++.h>
    using namespace std;
    set<int>s;stack<int>id;
    int main()
    {
    	int n,m;scanf("%d%d",&n,&m);
    	s.insert(0);s.insert(n+1);
    	while(m--)
    	{
    		char op[2];scanf("%s",op);
    		if(op[0]=='D')
    		{
    			int x;scanf("%d",&x);
    			s.insert(x);id.push(x);
    		}
    		else if(op[0]=='R')
    		{
    			if(s.size())
    			{
    				int x=id.top();
    				id.pop();s.erase(x);
    			}
    		}
    		else
    		{
    			int x;scanf("%d",&x);
    			if(s.find(x)!=s.end())puts("0");
    			else
    			{
    				auto it=s.lower_bound(x);
    				printf("%d\n",*it-*(--it)-1);
    			}
    		}
    	}
    	return 0;
    }
    
    • 0
      @ 2026-7-31 0:34:07

      这题用线段树,平衡树都能过

      但是其实我们可以用STL中的set

      设一个set记录当前被炸的房子编号,并且维护编号从小到大,当我们查询x时,找到在s中比x大的第一个和比x小的最后一个,位置之差减1即为答案。

      代码出奇的短

      #include<bits/stdc++.h>
      #define M 50010
      using namespace std;
      int q[M],tail,n,m;
      set<int> s;
      set<int>:: iterator it;
      int main()
      {
          scanf("%d%d",&n,&m);
          s.insert(0);
          s.insert(n+1);
          for(int i=1;i<=m;i++)
          {
              char c;
          cin>>c;//用scanf会把空格读进来
              if(c=='D')
              {
                  int x;                      // 加入x
                  scanf("%d",&x);
                  s.insert(x);
                  q[++tail]=x;
              }
              if(c=='Q')
              {
                  int x;                       //查询
                  scanf("%d",&x);
                  it=s.lower_bound(x);
                  if(*it==x)
                  {
                      printf("0\n");
                      continue;
                  }
                  int ans=*it-*(--it);
                  printf("%d\n",ans-1);
              }
              if(c=='R')                    //删除
              {
                  it=s.find(q[tail--]);
                  s.erase(it);
              }
          }
          return 0;
      }
      
      • 1

      信息

      ID
      1835
      时间
      500ms
      内存
      160MiB
      难度
      8
      标签
      递交数
      19
      已通过
      5
      上传者