题意:已知矩阵S,求序列a。已知矩阵Sij = “ + ” if ai + . . . + aj > 0; Sij = “ − ” if ai + . . . + aj < 0; and Sij = “0” otherwise.
分析:
1、由Sij = ‘+’ 可知,ai + . . . + aj > 0,即sum[j] - sum[i - 1] > 0,即sum[j] > sum[i - 1],即j优先级比i - 1高,由j向i - 1连一条有向边,i - 1入度+1。
2、按优先级由高到低,依次从10递减赋值,可知各前缀和的大小,由此得出序列a。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<stack> #include<deque> #include<queue> #include<list> #define lowbit(x) (x & (-x)) const double eps = 1e-8; inline int dcmp(double a, double b){ if(fabs(a - b) < eps) return 0; return a > b ? 1 : -1; } typedef long long LL; typedef unsigned long long ULL; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const LL LL_INF = 0x3f3f3f3f3f3f3f3f; const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const int MOD = 1e9 + 7; const double pi = acos(-1.0); const int MAXN = 10 + 10; const int MAXT = 100 + 10; using namespace std; char s[MAXT]; int indegree[MAXN]; int pic[MAXN][MAXN]; int sum[MAXN]; bool vis[MAXN]; int ans[MAXN]; int n; void topsort(){ int num = 10, cnt = 0; while(cnt < n + 1){ memset(vis, false, sizeof vis); for(int i = 0; i <= n; ++i){ if(!indegree[i]){ sum[i] = num; --indegree[i]; vis[i] = true; ++cnt; } } for(int i = 0; i <= n; ++i){ if(vis[i]){ for(int j = 0; j <= n; ++j){ if(pic[i][j]){ --indegree[j]; } } } } --num; } } int main(){ int T; scanf("%d", &T); while(T--){ memset(indegree, 0, sizeof indegree); memset(pic, 0, sizeof pic); scanf("%d", &n); scanf("%s", s); int cnt = 0; for(int i = 1; i <= n; ++i){ for(int j = i; j <= n; ++j){ char c = s[cnt++]; if(c == '+'){ pic[j][i - 1] = 1; ++indegree[i - 1]; } else if(c == '-'){ pic[i - 1][j] = 1; ++indegree[j]; } } } topsort(); for(int i = 1; i <= n; ++i){ if(i != 1) printf(" "); printf("%d", sum[i] - sum[i - 1]); } printf(" "); } return 0; }