http://vjudge.net/contest/view.action?cid=48251#problem/B
Description
Given a sequence of integers, a1, a2,..., an , we define its sign matrix S such that, for 1ijn , Sij = `` + " if ai +...+ aj > 0 ; Sij = `` - " ifai +...+ 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
Your program is to read from standard 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(1n10) , 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
Your program is to write to standard 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
思路:如果Sij>0的话,那么代表前缀和差Bj-Bi-1 >0 ,那么Bj > Bi-1,由此我们可以得到一系列的关系,
利用toposort排序后,得到一个递增或者递减的序列,就可以求出来各个数了
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
char a[10005];
int map[23][23],degree[23],s[23];
int n;
void init()
{
memset(map,0,sizeof(map));
memset(degree,0,sizeof(degree));
}
void toposort()
{
int low=-10;
int count=0;
while(count!=n+1)
{
int tag[23];
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,a);
init();
int cnt=0;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
char ss=a[cnt++];
if(ss=='+')
{
map[i-1][j]=1;
degree[j]++;
}
else if(ss=='-')
{
map[j][i-1]=1;
degree[i-1]++;
}
}
toposort();
int ans[23];
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;
}