链接
题解
非常巧妙地将问题转化成二分图判断。
i
,
j
i, j
i,j能够被压入同一个栈中的条件是不存在满足如下条件的元素
k
k
k:
a
[
k
]
<
a
[
i
]
<
a
[
j
]
,
i
<
j
<
k
a[k] < a[i] < a[j], i < j < k
a[k]<a[i]<a[j], i<j<k
因为当把
j
j
j压入栈中时要先将
i
i
i弹栈,而把
i
i
i弹栈之前必定已经将
k
k
k弹栈,这和
i
,
j
,
k
i,j,k
i,j,k的顺序是矛盾的。
将不能放入同一个栈中的元素两两连边,之后二分图判定,解决可行性之后贪心解决字典序问题即可
代码
#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 1; i <= (n); i++)
#define sqr(x) ((x) * (x))
const int maxn = 1000 + 50;
const int maxm = 1000000 + 50;
const int maxt = 500 + 5;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
const LL unit = 1LL;
const int INF = 0x3f3f3f3f;
const LL Inf = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-8;
const double inf = 1e15;
const double pi = acos(-1.0);
const LL mod = 1000000007;
struct Edge
{
int from, to, next;
Edge(int from = 0, int to = 0, int next = 0) : from(from), to(to), next(next) {}
} edge[maxm];
int n;
int a[maxn], dp[maxn];
int head[maxn], tot;
int color[maxn];
vector<char> ans;
void init()
{
memset(head, -1, sizeof(head));
memset(color, 0, sizeof(color));
tot = 0;
}
void AddEdge(int u, int v)
{
edge[tot] = Edge(u, v, head[u]);
head[u] = tot++;
}
bool dfs(int u, int fa, int tag)
{
color[u] = tag;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa || color[v] == -color[u])
continue;
if (color[v] == color[u] || !dfs(v, u, -tag))
return false;
}
return true;
}
stack<int> sta[2];
int main()
{
ios::sync_with_stdio(false);
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
int T;
cin >> T;
while (T--)
{
init();
ans.clear();
while (!sta[0].empty())
sta[0].pop();
while (!sta[1].empty())
sta[1].pop();
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
dp[n] = a[n];
for (int i = n - 1; i >= 1; i--)
dp[i] = min(dp[i + 1], a[i]);
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
if (a[i] < a[j])
{
int t = dp[j];
if (t < a[i])
{
AddEdge(i, j);
AddEdge(j, i);
}
}
bool ok = true;
for (int i = 1; i <= n; i++)
{
if (!color[i] && !dfs(i, -1, 1))
ok = false;
}
if (!ok)
{
cout << 0 << endl;
continue;
}
int flag = 1;
for (int i = 1; i <= n; i++)
{
if (color[i] == 1)
{
ans.push_back('a');
sta[0].push(a[i]);
}
else
{
ans.push_back('c');
sta[1].push(a[i]);
}
while ((!sta[0].empty() && sta[0].top() == flag) || (!sta[1].empty() && sta[1].top() == flag))
{
if (!sta[0].empty() && sta[0].top() == flag)
{
ans.push_back('b');
sta[0].pop();
}
else
{
ans.push_back('d');
sta[1].pop();
}
flag++;
}
}
cout << ans[0];
for (int i = 1; i < ans.size(); i++)
{
cout << " " << ans[i];
}
cout << endl;
}
return 0;
}