cqyz oj | 猜序列

Description

  对于一个序列a[1],a[2],…,a[n],我们可以计算出一个符号矩阵S,其中s[i][j]=a[i]+…+a[j]的正负号:连加和大于0则s[i][j]="+",小于0则s[i][j]="-",等于0则s[i][j]="0"。例如序列:-1,5,-4,2的矩阵如下: 
    
  根据序列A不难算出上述符号矩阵。你的任务上求解它的逆问题,即给出一个符号矩阵,找出一个对应的序列。输入保证存在一个满足上述条件的序列。可能满足的序列有多个,最大元素和最小元素尽量接近的解。

Input

  第1行为整数T,表示数据组数。  每组数据包含两行,第1行为整数n,表示序列长度。第2行有n*(n+1)/2个字符,有符号矩阵的每一行按照从上到下的顺序连接而成。

Output

  对于每组数据,在一行上输出n个绝对值不超过10的整数,即序列A。要求最大元素和最小元素尽量接近的解。

Sample Input 1 

3
4
-+0++++--+
2 
+++ 
5 
++0+-+-+--+-+--

Sample Output 1

-1 3 -2 1
1 1 
1 1 -2 3 -4

Hint

1<=T<=100
1<=n<=10

本题的核心思路是转化。

s[i][j]为连续子序列和,可以转化为sum[j]-sum[i-1](前缀和)。

由题目所给信息可以判断出 sum[j] 与 sum[i-1] 的大小关系,于是可以把 sum 的下标看作图的顶点,

将 sum[i-1]<sum[j] 转化为由 i-1 到 j 的一条有向边。

因为图中不可能存在环,所以该图为DAG图,又因为A[i]=A[i]-A[i-1],

所以可以运用拓扑排序把sum计算出来,进而求得A序列。

需要注意的是要使序列中最大值与最小值尽量接近,且序列为整数,

则sum之间的最小差值为1,进行拓扑排序BFS,求得所有sum。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 15;

int n;
vector<int> g[maxn];
int rd[maxn];
void input() {
    scanf("%d
", &n);
    for(int i=0; i<=n; i++)
        rd[i] = 0, g[i].clear();
    for(int i=1; i<=n; i++)
        for(int j=i; j<=n; j++) {
            char ch=getchar();
            if(ch == '+') {
                g[i-1].push_back(j);
                rd[j]++;
            }
            else if(ch == '-') {
                g[j].push_back(i-1);
                rd[i-1]++;
            }
        }
}

int sum[maxn];
void BFS() {
    memset(sum, 0, sizeof(sum));
    queue<int> Q;
    for(int i=0; i<=n; i++)
        if(!rd[i]) Q.push(i);
    while(!Q.empty()) {
        int u = Q.front(); Q.pop();
        for(int i=0; i<g[u].size(); i++) {
            int v = g[u][i];
            sum[v] = max(sum[v], sum[u]+1);
            if(!--rd[v]) Q.push(v);
        }
    }
}

int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        input();
        BFS();
        for(int i=1; i<n; i++) printf("%d ", sum[i]-sum[i-1]);
        printf("%d
", sum[n]-sum[n-1]);
    }
    return 0;
}
/*
3
4
-+0++++--+
2 
+++ 
5 
++0+-+-+--+-+--

*/
View Code
原文地址:https://www.cnblogs.com/de-compass/p/11800071.html