1.题目描述:点击打开链接
2.解题思路:本题利用拓扑排序解决。如果设S[i]表示前i个数的和,那么由符号矩阵可以得到B[i]之间的大小关系,可以用一个有向图来表示,然后求这个图的拓扑序,最后按照拓扑序逐个赋值即可。
3.代码:
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<list>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int,int> P;
const int maxn=10+5;
int n,g[maxn][maxn];
int c[maxn];
vector<int>topo;
bool dfs(int u)
{
c[u]=-1;
for(int v=0;v<=n;v++)
if(g[u][v])
{
if(c[v]<0)return false;
else if(!c[v])dfs(v);
}
c[u]=1;topo.push_back(u);
return true;
}
bool toposort()
{
topo.clear();
me(c);
for(int u=0;u<=n;u++)
if(!c[u])
if(!dfs(u))return false;
reverse(topo.begin(),topo.end());
return true;
}
int pa[maxn];
int find(int x)
{
return pa[x]==x?x:pa[x]=find(pa[x]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
char input[100],S[11][11];
scanf("%d%s",&n,input);
int idx=0;
for(int i=0;i<=n;i++)pa[i]=i;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
S[i][j]=input[idx++];
if(S[i][j]=='0')pa[j]=i-1;
}
me(g);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(S[i][j]=='-')g[find(j)][find(i-1)]=1;
if(S[i][j]=='+')g[find(i-1)][find(j)]=1;
}
toposort();
int sum[maxn],cur=0;
for(int i=0;i<=n;i++)
sum[topo[i]]=cur++;
for(int i=1;i<=n;i++)
{
sum[i]=sum[find(i)];
if(i>1)printf(" ");
printf("%d",sum[i]-sum[i-1]);
}
puts("");
}
}