Guess UVALive - 4255

题意:

  定义数组A的“符号矩阵”F,F[i][j]表示A[i] + A[i+1] + ... + A[j]。

  已知F,给出A的一个可能解。

分析:

  1. 利用前缀和。F[i][j[ 表示 S[j] - S[i-1]。

  2. 问题转化为已知 S[0] S[1] ... S[n] 的大小关系,并且已知 S[0] = 0,求 S 的可能解,进而可求出A数组。

  3. DAG,拓扑排序。涉及三种关系:小于、等于、大于。这里设定结点之间的关系为 <=, u->v,表示 u 小于等于 v。

  4. 拓扑序列求出后,利用S[0] = 0,以及“不等作差1处理”,求出S,再求A。

注意:

  1.  存储DAG直接使用符号矩阵F,但是现在结点数是 n ,F实际值给出了 G[0...n-1][1...n],即右上部分。

  2. j 是 i 的后继结点即 G[i][j] == '+' 而非G[i][j] == '-'。

#include<bits/stdc++.h>
using namespace std;


const int maxn = 10 + 3;
char g[maxn][maxn];
int vis[maxn];
int n;
int ans[maxn], cnt;

void dfs(int u)
{
    vis[u] = 1;
    for(int i = 0; i <= n; i++){
        if(u != i && !vis[i] && (g[u][i] == '+' || g[u][i] == '0')){
            dfs(i);
        }
    }
    ans[cnt--] = u;
}

void solve()
{
    memset(vis, 0, sizeof(vis));
    cnt = n;
    for(int i = 0; i <= n; i++){
        if(!vis[i]) dfs(i);
    }
    int s0;
    for(int i = 0; i <= n; i++){
        if(ans[i] == 0){
            s0 = i;
            break;
        }
    }
    //printf("s0: %d\n", s0);
    int s[maxn];
    s[0] = 0;
    for(int i = s0 - 1; i >= 0; i--){
        s[ans[i]] = s[ans[i+1]];
        if(g[ans[i]][ans[i+1]] == '+')
            s[ans[i]]--;
    }
    for(int i = s0 + 1; i <= n; i++){
        s[ans[i]] = s[ans[i-1]];
        if(g[ans[i]][ans[i-1]] == '-')
            s[ans[i]]++;
    }
    
    printf("%d", s[1]);
    for(int i = 2; i <= n; i++){
        printf(" %d", s[i] - s[i-1]);
    }
    printf("\n");
}

int main()
{
    int T;
    cin >> T;
    while(T--){
        cin >> n;
        char s[maxn*maxn];
        scanf("%s", s);
        int cnt = 0;
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j <= n; j++){
                char ch = s[cnt++];
                if(ch == '-') {g[i][j] = ch, g[j][i] = '+'; }
                else if(ch == '+') {g[i][j] = '+', g[j][i] = '-'; }
                else g[i][j] = g[j][i] = ch;
            }
        }
        for(int i = 0; i <= n; i++) g[i][i] = '0';
        solve();
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/sanshi-2018/p/10686275.html