首页 > 代码库 > D - Guess UVALive - 4255 拓扑排序
D - Guess UVALive - 4255 拓扑排序
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
拓扑排序:把sum(i,j)考虑成pre[j] - pre[i-1]的形式,然后可以建立图的关系,进行拓扑排序,从大到小,每一个拓扑序后面的点都比前面小,所以每当在拓扑排序里遇到该点(说明当前值比它大),都将遇到的点的sum 减一
注意i前缀序列是n+1项,【0,n】
#include<iostream>
#include<cstdio> #include<queue> #include<algorithm> #include<cstring> #include<string> using namespace std; #define MAXN 14 #define N 100 int in[MAXN], g[MAXN][MAXN]; int sum[MAXN]; char str[N]; int main() { int T, n; scanf("%d", &T); while (T--) { memset(g, 0, sizeof(g)); memset(in, 0, sizeof(in)); memset(sum, 0, sizeof(sum)); scanf("%d", &n); scanf("%s", str); int pos = 0; for (int i = 1; i <= n; i++) { for (int j = i; j <= n; j++) { char c; c = str[pos++]; if (c == ‘+‘) { g[j][i-1] = 1; in[i - 1]++; } else if(c == ‘-‘) { g[i - 1][j] = 1; in[j]++; } } } queue<int> q; while (!q.empty()) q.pop(); for (int i = 0; i <= n; i++) if (!in[i]) q.push(i); while (!q.empty()) { int tmp = q.front(); q.pop(); for (int i = 0; i <= n; i++)//必须从0开始 { if (g[tmp][i] == 1) { sum[i]--; if (--in[i] == 0) q.push(i); } } } for (int i = 1; i <= n; i++) { printf("%d", sum[i] - sum[i - 1]); if (i != n)printf(" "); else printf("\n"); } } }
D - Guess UVALive - 4255 拓扑排序