这道题我们可以通过给定的正负关系求出来各个和的大小关系,然后把S当成一个点,大小关系当成有向边,这样通过求一个拓扑序我们就可以得到一个大小关系,然后直接通过大小关系进行赋值,最后通过a[i] = S[i] - S[i - 1]求得原序列元素。(S[i]是前i项和……)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 15;
int dg[N], map[N][N], ans[N], n;
char ss[N * N];
void init(){
memset(map, 0, sizeof(map));
memset(dg, 0, sizeof(dg));
memset(ans, 0, sizeof(ans));
}
void topsort(){
queue<int> Q;
for (int i = 0; i <= n; i++)
if (!dg[i]) Q.push(i);
int cnt = 0;
while(!Q.empty()){
int u = Q.front();
Q.pop();
cnt += 1;
for (int i = 0; i <= n; i++){
if (map[u][i]){
dg[i] -= 1;
if (!dg[i]){
Q.push(i);
ans[i] = cnt;
}
}
}
}
}
int main(){
int cs;
scanf("%d", &cs);
while(cs--){
scanf("%d", &n);
scanf(" %s", ss);
init();
int h = 0;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++){
if (ss[h] == '+') {map[i - 1][j] = 1; dg[j] += 1;}
if (ss[h] == '-') {map[j][i - 1] = 1; dg[i - 1] += 1;}
h += 1;
}
topsort();
for (int i = 1; i < n; i++)
printf("%d ", ans[i] - ans[i - 1]);
printf("%d\n", ans[n] - ans[n - 1]);
}
return 0;
}