• 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)?'
    ':' ');
        }
        return 0;
    }
    

      

  • 相关阅读:
    Spring.NET学习笔记
    开源项目地址
    委托的实现匿名函数和朗姆达表达式
    c#事件与委托
    c# 时间戳转换
    List 排序
    DDD的好文章
    【转】理解JMeter聚合报告(Aggregate Report)
    【转】JMeter 通过 JDBC 访问 Oracle 和 MySQL
    【转】使用JMeter测试你的EJB
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4893321.html
Copyright © 2020-2023  润新知