UVA 1423 Guess 拓扑排序

来源:互联网 发布:游戏数据分析报告 编辑:程序博客网 时间:2024/04/29 01:31

题目描述:

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 41 − + 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

34-+0++++--+2+++5++0+-+-+--+-+--

Sample Output

-2 5 -3 13 41 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;}
0 0
原创粉丝点击