UVA 1423 Guess 拓扑排序

题目描述:

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+-+-+–+-+–
拓扑排序后的拓扑次序如下:
UVA 1423 Guess 拓扑排序_第1张图片

代码如下:

#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;
}

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