Guess

uvaLive4255:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2256

题意:对于一个序列,我们可以计算出一个符号矩阵,其中Sij为ai+...+aj的正负号,现在给你一个矩阵的上三角,求一个满足的序列

题解:对于这一题,按照白书上讲的,可以转化成前缀和来做。B【i】表示B[1]+B[2]+....+B[i]的和,sij=B[j]-B[i-1];如果Sij>0,就B[J]-B[I-1]>0,那么i-1和j建立一条边,相反的就j到i-1建边,如果等于0,不用考虑的,因为是n*(n-)/2个数,每个点和其他点都有关系,所以肯定会搜到。建好图之后,直接topsort 就可以得到一组B的值,然后相邻的相减,就可以得到一组a的值。这里,为方便,加入一个0点,并且B[0]=0;

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 int b[20],n;
 8 int deg[20];
 9 bool map[20][20];
10 void init(){
11      memset(deg,0,sizeof(deg));
12      memset(b,0,sizeof(b));
13      memset(map,0,sizeof(map));
14 }
15 void topsort(){
16    b[0]=0;
17    queue<int>Q;
18    for(int i=0;i<=n;i++){
19        if(deg[i]==0){
20          deg[i]--;
21          Q.push(i);
22          b[i]=0;
23        }
24    }
25    while(!Q.empty()){
26        int u=Q.front();
27        Q.pop();
28        for(int i=0;i<=n;i++){
29           if(map[u][i]){
30                deg[i]--;
31                if(deg[i]==0){
32                  b[i]=b[u]+1;
33                  deg[i]--;
34                  Q.push(i);
35                }
36           }
37        }
38    }
39 }
40 char temp;
41 int main(){
42    int test;
43    scanf("%d",&test);
44    while(test--){
45      scanf("%d",&n);
46      init();
47      for(int i=0;i<n;i++){
48         for(int j=i+1;j<=n;j++){
49             cin>>temp;
50             if(temp=='+'){
51                 deg[j]++;
52                 map[i][j]=1;
53             }
54             else if(temp=='-'){
55                deg[i]++;
56                map[j][i]=1;
57             }
58         }
59      }
60       topsort();
61       for(int i=1;i<=n;i++){
62         if(i<n)printf("%d ",b[i]-b[i-1]);
63         else
64             printf("%d\n",b[i]-b[i-1]);
65       }
66    }
67 }
View Code

 

posted on 2014-06-18 23:28  天依蓝  阅读(130)  评论(0编辑  收藏  举报

导航