UVALive 4255 拓扑排序

http://vjudge.net/contest/view.action?cid=48251#problem/B

Description

Given a sequence of integers, a1a2,..., 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 (a1a2a3a4) = (- 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为ai+...+aj的正负号,现在给你一个矩阵的上三角,求一个满足的序列

思路:如果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;
}


你可能感兴趣的:(UVALive 4255 拓扑排序)