Train Wreck

题意大概是任意给定入栈顺序,和入栈的元素,每一次入栈之后,此时栈中的元素的 元素和种类 与之前不能完全相同

思路很好想,实现需要一定的思路

通过模拟,我们可以发现,将每一次入栈之后的栈中元素的,可以用类似于字典树来表示

根据该题意,这样构造成的一棵树一定不能出现子节点相同的情况,否则无法构造

贪心地想,我们将出现最多次数的元素优先放在最靠近根节点,这么做可以尽量保证需要不同的元素时,元素的种类足够

点击查看代码
#include<bits/stdc++.h>

using namespace std;
#define x first
#define y second
typedef pair<int,int> pii; 

priority_queue<pii> q;
int cnt=0;
int n;
const int maxn=5e6+10;
struct node{
	int v,next;
}e[maxn];
int head[maxn];

int f[maxn];
string s;
int ans[maxn];
int color[maxn];
bool flag=0;
vector<pii> p; 
void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int u){
	if(flag) return ;
    p.clear();
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].v;
		if(!q.empty()){
			auto t=q.top();
			ans[v]=t.y;
			q.pop();
			if(t.x>=2) p.push_back({t.x-1,t.y});
		}
		else {
			flag=true;return ;
		}
	}
	for(auto i:p) q.push(i);
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].v;
		dfs(v);
		if(flag) return ;
	}
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
	cin>>n>>s;
	for(int i=0;i<n;++i){
		int x;cin>>x;
		color[x]++;
	}
	for(int i=1;i<=n;++i)
		if(color[i])
			q.push({color[i],i});
	int p=0,now=0;
	for(int i=0;i<2*n-1;++i){
		if(s[i]=='('){
			add(now,++p);
			f[p]=now;
			now=p;
		}
		else now=f[now];
	}
	dfs(0);
	if(flag) cout<<"NO"<<endl;
	else {	
        cout<<"YES"<<endl;
        for(int i=1;i<=n;++i) cout<<ans[i]<<" ";
        cout<<endl;
	}
	return 0;
}

后记

通过这个题了,我们可以收获的是,如果存在元素和元素之间的关系,我们可以考虑建图,在图上遍历,操作会更加简单

posted @ 2025-05-03 18:37  归游  阅读(12)  评论(0)    收藏  举报