题意:对于一个序列,我们可以计算出一个符号矩阵,其中Sij为ai+...+aj的正负号,
现在给你一个矩阵的上三角,求一个满足的序列
思路:如果Sij>0的话,那么代表前缀和差Bj-Bi-1 >0 ,那么Bj > Bi-1,由此我们可以得到一系列的关系,利用toposort排序后,得到一个递增或者递减的序列,就可以求出来各个数了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 20;
int n,degree[MAXN];
int map[MAXN][MAXN],s[MAXN],ans[MAXN];
char text[1000];
void init(){
memset(map,0,sizeof(map));
memset(degree,0,sizeof(degree));
}
void toposort(){
int count = 0,low = -10;
while (count != n+1){
int tag[MAXN];
memset(tag,0,sizeof(tag));
for (int i = 0; i <= n; i++)
if (degree[i] == 0){
s[i] = low;
degree[i] = -1;
tag[i] = 1;
count++;
}
low++;
for (int i = 0; i <= n; i++)
if (tag[i]){
for (int j = 0; j <= n; j++)
if (map[i][j])
degree[j]--;
}
}
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d%s",&n,text);
init();
int cnt = 0;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++){
char a = text[cnt++];
if (a == '+'){
map[i-1][j] = 1;
degree[j]++;
}
else if (a == '-'){
map[j][i-1] = 1;
degree[i-1]++;
}
}
toposort();
for (int i = 1; i <= n; i++)
ans[i] = s[i] - s[i-1];
for (int i = 1; i < n; i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}