Given a sequence of integers, a1, a2,..., an , we define its sign matrix S such that, for 1ijn , 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.
Your program is to read from standard input. The input consists of T test cases. The number of test cases Tis given in the first line of the input. Each test case consists of two lines. The first line contains an integer n (1n10) , 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.
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.
3 4 -+0++++--+ 2 +++ 5 ++0+-+-+--+-+--
-2 5 -3 1 3 4 1 2 -3 4 -5思路:设f[i]=ans[0]+..+ans[i],那么上述的i行j列+,-,0关系就表示为f[j]>f[i-1],f[j]<f[i-1],f[j]==f[i-1];
来个拓扑排序,就好了,其中0比较讨厌,那就不管它,只要再拓扑排序时,将没有入度的点都置成一样的值,就一定满足了相等的情况。
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using namespace std; const int mm=15; vector<int> g[mm]; int id[mm],f[mm],ans[mm]; int cas,n; void get(int n) { char c; memset(g,0,sizeof(g)); memset(id,0,sizeof(id)); for(int i=1;i<=n;++i) for(int j=i;j<=n;++j) { while(1) { c=getchar(); if(c=='+'){g[j].push_back(i-1);++id[i-1];break;} else if(c=='-'){g[i-1].push_back(j);++id[j];break;} else if(c=='0'){/**g[j][i-1]=g[i-1][j]=2;*/break;} } } } void topsort() { int top=-1,high=10; for(int i=0;i<=n;++i) if(!id[i]) id[i]=top,top=i; for(int i=0;i<=n;++i) { int kop=-1; if(top==-1){return;} while(top!=-1) { int num=top;top=id[top];f[num]=high; int m=g[num].size(); for(int i=0;i<m;++i) if(--id[g[num][i]]==0) { id[g[num][i]]=kop;kop=g[num][i]; } } top=kop; high--; } } int main() { while(~scanf("%d",&cas)) { while(cas--) { scanf("%d",&n); get(n); topsort(); for(int i=1;i<=n;++i) ans[i]=f[i]-f[i-1]; for(int i=1;i<=n;++i) printf("%d%c",ans[i],i==n?'\n':' '); } } }