zoukankan      html  css  js  c++  java
  • UVAlive4255_Guess

    题目很好很有意思。

    告诉你n个序列中,任意一个连续子序列的和与0相比较的结果。

    构造一个满足条件的序列。

    对于从x->y这一段的和,如果大于0,那么sum[x]>sum[y-1],显然我们可以得到每一个sum的大小关系。由于这个满足条件的sum关系已经考虑了所有的源系列的大小关系,所以只要我们生成了一个满足条件的sum序列能够满足其大小关系,那么a[i]=sum[i]-sum[i-1]就一定是满足条件的。

    根据拓扑排序我们可以知道每一个sum之间的大小关系,中间包含于sum[0]=0的大小关系,我们只要依次按照大小一个一个往里面填数字就好了。

    召唤代码君:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    int a[11][11],d[11],eq[11],Q[121],top,totdone,tmp,father;
    int f[121];
    bool vis[11];
    int n,T;
    char s[121];
    
    int main()
    {
        int cur;
        scanf("%d",&T);
        while (T--)
        {
            memset(a,0,sizeof a);
            memset(d,0,sizeof d);
            scanf("%d",&n);
            for (int i=0; i<=n; i++) eq[i]=-1,vis[i]=false;
            scanf("%s",s);
            cur=0;
            for (int i=1; i<=n; i++)
                for (int j=i; j<=n; j++,cur++)
                {
                    if (s[cur]=='+')
                    {
                        a[i-1][j]=1;
                        d[j]++;
                    }
                    else if (s[cur]=='-')
                    {
                        a[j][i-1]=1;
                        d[i-1]++;
                    }
                }
            top=totdone=0;
            while (totdone<n+1)
            {
                tmp=9999;
                for (int i=0; i<=n; i++)
                    if (!vis[i] && d[i]<tmp) tmp=d[i];
    
                queue<int> que;
                for (int i=0; i<=n; i++)
                    if (!vis[i] && d[i]==tmp) que.push(i);
    
                father=-1;
                while (!que.empty())
                    {
                        int i=que.front();
                        que.pop();
                        vis[i]=true;
                        totdone++;
                        if (father==-1) { father=i,Q[++top]=i; }
                            else eq[i]=father;
                        for (int j=0; j<=n; j++)
                            if (a[i][j]) d[j]--;
                    }
            }
            for (int i=1; i<=top; i++)
                if (Q[i]==0)
                {
                    tmp=i;
                    break;
                }
            if (eq[0]!=-1)
                for (int i=0; i<=n; i++)
                    if (Q[i]==eq[0]) tmp=i;
            cur=1;
            for (int i=tmp+1; i<=top; i++) f[Q[i]]=cur++;
            cur=-1;
            for (int i=tmp-1; i>0; i--) f[Q[i]]=cur--;
            for (int i=0; i<=n; i++)
                if (eq[i]!=-1) f[i]=f[eq[i]];
            for (int i=1; i<=n; i++)
            {
                printf("%d",f[i]-f[i-1]);
                if (i<n) printf(" ");
            }
            printf("
    ");
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    Python元组、列表、字典
    测试通过Word直接发布博文
    Python环境搭建(windows)
    hdu 4003 Find Metal Mineral 树形DP
    poj 1986 Distance Queries LCA
    poj 1470 Closest Common Ancestors LCA
    poj 1330 Nearest Common Ancestors LCA
    hdu 3046 Pleasant sheep and big big wolf 最小割
    poj 3281 Dining 最大流
    zoj 2760 How Many Shortest Path 最大流
  • 原文地址:https://www.cnblogs.com/lochan/p/3842912.html
Copyright © 2011-2022 走看看