LA-4255 Guess (拓扑排序+构造)

题目大意:一个未知的整数序列,给出其任意一个区间和的正负,还原这个序列。任意一个满足条件的序列即可。

题目分析:将连续区间和转化为前缀和之差,sumx-1与sumy的大小关系已知,以此建立一条有向边,做拓扑排序。根据sum0=0,可以构造出所有的前缀和,再取两前缀和之差便得答案。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;

char p[15][15];
int in[15],ans[15],mp[15][15],mp1[15][15];
vector<int>v;
queue<int>q;

void kahn(int n)
{
    v.clear();
    while(!q.empty())   q.pop();
    for(int i=0;i<=n;++i)
        if(in[i]==0)
            q.push(i);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        v.push_back(u);
        for(int i=0;i<=n;++i){
            if(mp[u][i]){
                mp[u][i]=0;
                --in[i];
                if(in[i]==0)
                    q.push(i);
            }
        }
    }
}

void solve(int n)
{
    ans[0]=0;
    int pos;
    for(int i=0;i<=n;++i){
        if(v[i]==0){
            pos=i;
            break;
        }
    }
    for(int i=pos-1;i>=0;--i){
        if(!mp1[v[i]][v[i+1]])///如果跟相邻点没有明确的大小关系,则取相等。。下同。。。
            ans[v[i]]=ans[v[i+1]];
        else
            ans[v[i]]=ans[v[i+1]]-1;
    }
    for(int i=pos+1;i<=n;++i){
        if(!mp1[v[i-1]][v[i]])
            ans[v[i]]=ans[v[i-1]];
        else
            ans[v[i]]=ans[v[i-1]]+1;
    }
}

int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        memset(in,0,sizeof(in));
        memset(mp,0,sizeof(mp));
        memset(mp1,0,sizeof(mp1));
        scanf("%d",&n);
        getchar();
        for(int i=0;i<n;++i){
            for(int j=i+1;j<=n;++j){
                p[i][j]=getchar();
                if(p[i][j]=='+'){
                    mp1[i][j]=mp[i][j]=1;
                    ++in[j];
                }
                if(p[i][j]=='-'){
                    mp1[j][i]=mp[j][i]=1;
                    ++in[i];
                }
            }
        }
        kahn(n);
        solve(n);
        for(int i=1;i<=n;++i)
            printf("%d%c",ans[i]-ans[i-1],(i==n)?'\n':' ');
    }
    return 0;
}

  

posted @ 2015-10-19 22:28  20143605  阅读(476)  评论(0编辑  收藏  举报