• 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)
  • 相关阅读:
    【JDK源码】从源码看公平锁和非公平锁得区别
    【spring源码解读】spring加载流程refresh之prepareBeanFactory(beanFactory)
    【JDK源码】Synchronized关键字原理,和锁的膨胀过程
    【Spring源码解读】BeanPostProcessor 接口解读
    【spring源码】spring的循环依赖
    JS-04 JS中的函数都是按值传递的
    CSS-03 queue方法
    CSS-02 BFC的理解
    CSS-01 CSS代码标准和规范
    JS-03 牛客网练习
  • 原文地址:https://www.cnblogs.com/lochan/p/3842912.html
Copyright © 2020-2023  润新知