• 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)
  • 相关阅读:
    使用Yeoman搭建 AngularJS 应用 (9) —— 让我们搭建一个网页应用
    advance shading——菲涅耳现象
    现代编译原理--第六章(中间树 IR Tree 含源码)
    现代编译原理--第五章(活动记录)
    现代编译原理--第四章(语义分析以及源码)
    现代编译原理--第三章(抽象语法树以及源码)
    现代编译原理--第二章(语法分析之LL(K))
    现代编译原理--第一章(词法分析)
    advance shading--BRDF
    个人作业——软件工程实践总结作业
  • 原文地址:https://www.cnblogs.com/lochan/p/3842912.html
Copyright © 2020-2023  润新知