• test20181024 kun


    题意


    分析

    考场做法

    任意状态只有两种决策,进栈或出栈。

    由于元素互不相同,所以选择的关键在于栈顶元素是否在它和带插入元素组成的集合中是最大的。

    用stack和set维护。时间复杂度(O(n log n))

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #include<cassert>
    #define rg register
    #define il inline
    #define co const
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> il T read()
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return data*w;
    }
    template<class T> il T read(T&x)
    {
    	return x=read<T>();
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=1e6+7;
    int a[MAXN];
    stack<int>S;
    set<int>H;
    
    int main()
    {
      freopen("kun.in","r",stdin);
      freopen("kun.out","w",stdout);
    	rg int n=read<int>();
    	for(rg int i=1;i<=n;++i)
    	{
    		read(a[i]);
    		H.insert(a[i]);
    	}
    	rg int p=1;
    	for(rg int i=1;i<=2*n;++i)
    	{
    //		cerr<<"pro "<<i<<endl;
    		if(!S.empty()&&S.top()==*H.rbegin()) // pop
    		{
    //			cerr<<"  case 1"<<endl;
    			printf("%d ",S.top());
    			H.erase(S.top());
    			S.pop();
    			if(!S.empty())
    				H.insert(S.top());
    		}
    		else // push
    		{
    //			cerr<<"  case 2"<<endl;
    			if(!S.empty())
    				H.erase(S.top());
    			S.push(a[p++]);
    		}
    	}
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    

    标解

    要使序列字典序最大,首先它的第一个元素必须是最大元素,按此思路贪心即可。要求出下一步可输出元素的最大者,只需要取下一个元素所在的后缀与当前栈顶元素中的最大值。后缀最大值可以在线性时间内预处理出。

    实际上维护最大值没必要用set,观察发现我们只需了解每个后缀的最大值,所以用数组维护。

    时间复杂度(O(n))

    //Achen
    #include<bits/stdc++.h>
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=1e6+7;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,a[N],mx[N];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int sta[N],top;
    
    #define ANS
    int main() {
    #ifdef ANS
        freopen("kun.in","r",stdin);
        freopen("kun.out","w",stdout);
    #endif
    	read(n);
    	For(i,1,n) read(a[i]);
    	Rep(i,n,1) {
    		mx[i]=mx[i+1];
    		if(a[i]>mx[i]) mx[i]=a[i];
    	}
    	For(i,1,n) {
    		while(top&&sta[top]>mx[i]) {
    			printf("%d ",sta[top--]);
    		}
    		sta[++top]=a[i];
    	}
    	while(top) {
    		printf("%d ",sta[top--]);
    	}
    	puts("");
        Formylove;
    }
    
    静渊以有谋,疏通而知事。
  • 相关阅读:
    读写二进制c# 二进制读写
    重构风险程序员一定要遵守的规则
    文件区域使用fcntl锁定文件,并且测试
    数据清空js清空div里的数据问题
    模板缓存ThinkPHP中的模板引擎和视图层
    描述null11121 Base 2
    操作系统请求操作系统 算法
    工程项目eclipse项目名前出现红色感叹号,小红叉解决
    程序链接关于静态链接,动态链接,共享库,ABI的一些记录(os学习)
    NMAKE命令行编译
  • 原文地址:https://www.cnblogs.com/autoint/p/9845358.html
Copyright © 2020-2023  润新知