UValive 4255 Guess(拓扑排序)

TAT~图论好难,3个月前就见过这道题了,当初拿过来这题根本没感觉是个图论。

而后听了嘉神简单讲了下思路也是糊里糊涂,只知道是个拓扑排序问题。如今再看到这题依旧没个敲的思路。

直到盯着队友的代码看了半个小时,又手跑了一趟,才终于明白个所以然,感觉好神奇= =|||

【虽然能感觉到自己有进步,但真不知道什么时候才能把自己这颗“雪球”滚的越来越大】

Description

Download as PDF

Given a sequence of integers, a1a2,..., an , we define its sign matrix S such that, for 1$ \le$i$ \le$j$ \le$n , Sij = `` + " if ai +...+ aj > 0 ; Sij = `` - "if ai +...+ 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(1$ \le$n$ \le$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

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

解题思路:首先是要把求每个位置上的值转化为求 “前缀和之差”。

input数组中,input[i]中存的值,表示有多少个"前缀和"比"前i个数的和"大。

vec数组中,vec[i]中存的值x,表示"前x数的和"比"前i个小"。

然后假设最大的前缀和为20,依次第二大19,第三大18递减得到。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <iostream>
using namespace std;
#define maxn 15
char ch[maxn * maxn];
int t, n, k, ans;
int input[maxn], sum[maxn];
vector<int> vec[maxn];
void init() {
    k = 0; ans = 20;
    memset(input, 0, sizeof(input));
    memset(sum, 0, sizeof(sum));
    for(int i = 0; i <= n; i++)
        vec[i].clear();
}
void add_edge() {
    for(int i = 1; i <= n; i++) {
        for(int j = i; j <= n; j++) {
            char temp = ch[k++];
            if(temp == '+') {
                input[i - 1]++;
                vec[j].push_back(i - 1);
            }
            else if(temp == '-') {
                input[j]++;
                vec[i - 1].push_back(j);
            }
        }
    }
}
void topsort() {
    stack<int> s;
    for(int i = 0; i <= n; i++)
        if(input[i] == 0) {
            s.push(i);
            sum[i] = ans;
            input[i] = -1;
        }
    while(!s.empty()) {
        int x = s.top(); s.pop();
        ans--; input[x] = -1;
        for(int i = 0; i < vec[x].size(); i++) {
            input[vec[x][i]]--;
            if(input[vec[x][i]] == 0) {
                s.push(vec[x][i]);
                input[vec[x][i]] = -1;
                sum[vec[x][i]] = ans;
            }
        }
    }
}
int main() {
    scanf("%d", &t);
    while(t--) {
        scanf("%d%s", &n, ch);
        init();
        add_edge();
        topsort();
        for(int i = 1; i <= n; i++) {
            if(i == 1) printf("%d", sum[i] - sum[i - 1]);
            else printf(" %d", sum[i] - sum[i - 1]);
        }
        printf("\n");
    }
    return 0;
}


posted @ 2014-10-09 11:49  gaoxiang36999  阅读(167)  评论(0)    收藏  举报