• UOJ174 新年的破栈


    http://uoj.ac/problem/174

    有一列数,每次可以将当前数索引最小的一个放入栈中,或从栈底或栈顶取出一个数
    依次排列取出的数使之形成一个新的序列,让这个序列的字典序最小


    因为要字典序最小,那肯定是贪心的
    每次,考虑能取出(就是让他进入序列)三种数

    • 栈顶
    • 栈底
    • 目前还没入栈的数中的最小的,当然如果去这种数要把索引在他前面的没有入栈的数都入栈

    然后就直接比较这三个数谁大谁小就行了,对于还没入栈的数我还用了个带删堆维护。。。。感觉麻烦点了
    比较时细节上也有些麻烦,不过还好,整个题还是挺简单的

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<queue>
    #include<iomanip>
    #include<cstring>
    #define reg register
    #define EN puts("")
    inline int read(){
    	register int x=0;register int y=1;
    	register char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    #define N 100005
    struct data{
    	int x,id;
    };
    inline int operator < (data a,data b){return a.x>b.x;}
    struct Heap{
    	std::priority_queue<data>insert,deleted;
    	inline void push(data a){insert.push(a);}
    	inline void del(data a){deleted.push(a);}
    	inline data top(){
    		while(!deleted.empty()&&!insert.empty()&&deleted.top().x==insert.top().x) deleted.pop(),insert.pop();
    		if(insert.empty()) return (data){(int)2e9,0};
    		return insert.top();
    	}
    	inline void clear(){
    		while(!insert.empty()) insert.pop();
    		while(!deleted.empty()) deleted.pop();
    	}
    }heap;
    int n,a[N];
    int stack[N];
    int main(){int T=read();while(T--){
    	n=read();
    	for(reg int i=1;i<=n;i++) a[i]=read(),heap.push((data){a[i],i});
    	reg int left=0,right=-1,pos=1;
    	for(reg int i=1;i<=n;i++){
    		if(left<=right&&heap.top().x>stack[left]&&heap.top().x>stack[right]){
    			if(stack[left]<stack[right]) printf("%d ",stack[left++]);
    			else printf("%d ",stack[right--]);
    		}
    		else if(heap.top().x<std::min(stack[left],stack[right])||left>right){
    			int id=heap.top().id;
    			printf("%d ",heap.top().x);
    			heap.del((data){a[id],id});
    			while(pos<id){
    				stack[++right]=a[pos];
    				heap.del((data){a[pos],pos});
    				pos++;
    			}
    			pos++;
    		}
    		else{
    			if(stack[left]<stack[right]) printf("%d ",stack[left++]);
    			else printf("%d ",stack[right--]);
    		}
    	}
    	heap.clear();EN;
    }
    	return 0;
    }
    
  • 相关阅读:
    linux基础名词
    计算机基础
    c++ 构造函数
    c++ stdafx.h、targetver.h文件
    centos7初步命令
    mysql 操作表的语句
    后台返回API数据格式
    nginx相关知识
    js复制内容到剪贴板格式化粘贴到excel中
    PHP开启错误提示
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/13661149.html
Copyright © 2020-2023  润新知