Given a sequence of integers, a1, a2, … , an, we define its sign matrix S such that, for 1 ≤ i ≤ j ≤ n, Sij = “ + ” if ai + … + aj > 0; Sij = “ − ” if ai + … + aj < 0; and Sij = “0” otherwise.
For example, if (a1, a2, a3, a4) = (−1, 5, −4, 2), then its sign matrix S is a 4 × 4 matrix:
1 2 3 4
1 − + 0 +
2 + + +
3 − −
4 +
We say that the sequence (−1, 5, −4, 2) generates the sign matrix. A sign matrix is valid if it can be generated by a sequence of integers.
Given a sequence of integers, it is easy to compute its sign matrix. This problem is about the opposite direction: Given a valid sign matrix, find a sequence of integers that generates the sign matrix.
Note:
that two or more different sequences of integers can generate the same sign matrix. For example, the sequence (−2, 5, −3, 1) generates the same sign matrix as the sequence (−1, 5, −4, 2).
Write a program that, given a valid sign matrix, can find a sequence of integers that generates the sign matrix. You may assume that every integer in a sequence is between −10 and 10, both inclusive.
Input
The input consists of T test cases. The number of test cases T is given in the first line of the input.
Each test case consists of two lines. The first line contains an integer n (1 ≤ n ≤ 10), where n is the length of a sequence of integers. The second line contains a string of n(n + 1)/2 characters such that the first n characters correspond to the first row of the sign matrix, the next n − 1 characters to the second row, …, and the last character to the n-th row.
Output
For each test case, output exactly one line containing a sequence of n integers which generates the sign matrix. If more than one sequence generates the sign matrix, you may output any one of them. Every integer in the sequence must be between −10 and 10, both inclusive.
Sample Input
3
4
-+0++++--+
2
+++
5
++0+-+-+--+-+--
Sample Output
-2 5 -3 1
3 4
1 2 -3 4 -5
char[i]每一个字符’+’、’-‘、’0’表示从a[1]、a[2]、a[3]……a[i]之和与0相比,大于0为’+’,小于0为’-‘,等于0为’0’。现给你如下的字符串,求可能的a数列。(答案有多种可能 任意输出其中一种即可)。
拓扑排序:将无环有向图排成简单的线性序列,其中 《u,v》 表示u顶点到v顶点有一条有向边。
因为题目所给字符串实际上表示的是数组各个元素与0的大小关系,那么我们不妨加入元素0进行拓扑排序。
举例:
5
++0+-+-+–+-+–
拓扑排序后的拓扑次序如下:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int T;
int n;
char s[100];
bool map[15][15];
int a[15];
int in[15];
void topsort()
{
queue <int> q;
for(int i=0; i<=n; i++)
{
if (!in[i]) q.push(i);
}
int cnt=0;
while(!q.empty())
{
int tmp=q.front();
q.pop();
cnt++;
for(int i=0; i<=n; i++)
{
if (map[tmp][i])//a[tmp]指向a[i],a[i]大于a[tmp]
{
in[i]--;
if (!in[i])//如果没有大于a[i]的元素,入队
{
q.push(i);
a[i]=cnt;
}
}
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(in,0,sizeof(in));
memset(map,0,sizeof(map));
memset(a,0,sizeof(a));
scanf("%d",&n);
scanf("%s",s);
int k=0;
for(int i=1; i<=n; i++)
{
for(int j=i; j<=n; j++)
{
if (s[k]=='+')
{
map[i-1][j]=1; //a[i-1]小于a[j],将a[i-1]指向a[j],将指向a[j]的节点数+1
in[j]++;
}
if (s[k]=='-')
{
map[j][i-1]=1; //a[i-1]大于a[j],将a[j]指向a[i-1],将指向a[i-1]的节点数+1
in[i-1]++;
}
k++;
}
}
// for(int i=0; i<=n; i++)
// {
// printf("%d ",in[i]);
// }
// printf("\n");
topsort();
for(int i=1; i<=n; i++)
{
printf("%d ",a[i]-a[i-1]);
}
printf("\n");
}
return 0;
}