D - Guess UVALive - 4255 拓扑排序

Posted joeylee97

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 拓扑排序的主要内容,如果未能解决你的问题,请参考以下文章

UVALive - 4255 - Guess (拓扑排序)

拓扑排序或差分约束Guess UVALive - 4255

寒假特训题解

UVAlive4097 Yungom(思路)

UValive4195 Heroes of Money and Magic

cf1556D. Take a Guess