zoukankan      html  css  js  c++  java
  • P7726-天体探测仪(Astral Detector)【构造】

    正题

    题目链接:https://www.luogu.com.cn/problem/P7726


    题目大意

    一个长度为(n)的排列,给出(n)个可重集(S_i)表示所有长度为(i)的区间的最小值构成的集合。

    求构造这个排列。

    (1leq nleq 800)


    解题思路

    对于一个数字,如果在(S_i)中的出现次数小于(i)时,证明包含它的区间中拥有不是它为最小值的情况。
    所以每个数字我们找到出现次数小于(i)的第一个(S_i),那么它离它左右两边比他小的数字的距离就是(i-1)

    然后考虑再求出另一边的距离,当某个时候(S_i)中不包含数字(x)时,那么证明(x)距离两边的距离和小于(i),找到一个位置就可以算出另一边的距离。

    然后直接从小到大找满足条件的位置插入即可。

    时间复杂度(O(n^2))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    using namespace std;
    const int N=810;
    int n,c[N],L[N],R[N],ans[N];
    set<int> s;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		int x;
    		memset(c,0,sizeof(c));
    		for(int j=1;j<=n-i+1;j++){
    			scanf("%d",&x);
    			c[x]++;
    		}
    		for(int j=1;j<=n;j++){
    			if(!L[j]&&c[j]!=i)L[j]=i-1;
    			if(!R[j]&&!c[j])R[j]=i-L[j];
    		}
    	}
    	R[1]=n-L[1]+1;
    	s.insert(0);s.insert(n+1);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(ans[j])continue;
    			int l=(*s.lower_bound(j))-j;
    			int r=j-*(--s.upper_bound(j));
    			if(l>r)swap(l,r);
    			if(l==L[i]&&r==R[i])
    			{ans[j]=i;s.insert(j);break;}
    		}
    	}
    	for(int i=1;i<=n;i++)
    		printf("%d ",ans[i]);
    }
    
  • 相关阅读:
    nginx中的超时配置
    ubuntu系统TCP连接参数优化-TIME_WAIT过多解决办法
    python中的raise用法
    pip安装各种模块
    ubuntu上安装python的ldap模块
    docker 打印带时间的日志
    基于Xilinx Zynq Z7045 SoC的CNN的视觉识别应用
    VIVADO下IBERT使用指南
    菜根谭全文及译文
    bit,Byte,Word,DWORD(DOUBLE WORD,DW)
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15012519.html
Copyright © 2011-2022 走看看