题目给出的是Sij的正负号,Sij=ai+...+aj,所以令前缀和Bi=a0+a1+..+ai,a0=0,B0=0,则有Sij=Bj-B(i-1);
由此构造出Bi的拓扑序列,只要每个拓扑序列相邻的Bi的值只相差1,那样总共只有不会超过10个Bi,最大的Bi和最小的Bi的差值的绝对值小于10,
因为ai=Bi-B(i-1),ai的绝对值就必然不超出10;
1 #include <stdio.h> 2 #include <string.h> 3 #define CL(x) memset(x,0,sizeof(x)) 4 const int maxn=15; 5 bool map[maxn][maxn]; 6 char str[maxn*maxn]; 7 int din[maxn]; 8 int dou[maxn]; 9 int c[maxn]; 10 int topo[maxn]; 11 int b[maxn]; 12 int tp,n; 13 bool dfs(int u) 14 { 15 c[u]=-1; 16 for(int v=0;v<=n;v++)if(map[u][v]){; 17 if(!c[v] && !dfs(v))return false; 18 } 19 c[u]=1;topo[tp--]=u; 20 return true; 21 } 22 bool toposort() 23 { 24 tp=n; 25 CL(c); 26 for(int u=0;u<=n;u++)if(!c[u]) 27 if(!dfs(u)) return false; 28 return true; 29 } 30 31 int main() 32 { 33 int t; 34 scanf("%d",&t); 35 while(t--){ 36 int p; 37 scanf("%d",&n); 38 scanf("%s",str); 39 p=0;CL(din);CL(dou);CL(map); 40 int i; 41 for(i=0;i<n;i++)for(int j=i+1;j<=n;j++){ 42 switch(str[p]){ 43 case '-':map[i][j]=1; 44 break; 45 case '+':map[j][i]=1; 46 break; 47 case '0':map[i][j]=map[j][i]=1; 48 break; 49 } 50 p++; 51 } 52 if(toposort()) 53 for(i=0;i<=n;i++)if(topo[i]==0)break; 54 b[topo[i]]=0; 55 for(int j=i-1;j>=0;j--){ 56 if(map[topo[j+1]][topo[j]] && map[topo[j]][topo[j+1]]) 57 b[topo[j]]=b[topo[j+1]]; 58 else 59 b[topo[j]]=b[topo[j+1]]+1; 60 } 61 for(int j=i+1;j<=n;j++){ 62 if(map[topo[j]][topo[j-1]] && map[topo[j-1]][topo[j]]) 63 b[topo[j]]=b[topo[j-1]]; 64 else 65 b[topo[j]]=b[topo[j-1]]-1; 66 } 67 for(i=1;i<=n;i++){ 68 if(i!=1)putchar(' '); 69 printf("%d",b[i]-b[i-1]); 70 } 71 putchar(' '); 72 } 73 return 0; 74 }