Uvalive 4255 - Guess(思维+拓扑排序)

题目链接 https://vjudge.net/problem/UVALive-4255

【题意】
对于一个序列a1,a2…an,我们可以计算出一个符号矩阵s,s[i][j]为ai+…+aj的正负号,现在给出一个符号矩阵,求一个满足该符号矩阵的序列,每个整数的绝对值不超过10.

【思路】
大白书310页例题,将连续和转为前缀和,即ai+…+aj=b[j]-b[i-1],然后根据符号矩阵即可得出一些b[i]和b[j]的大小关系,用小于关系作为边建立有向图,那么这个图的拓扑排序序列便是一个可行解,因为n<=10,所以顶点编号最大只有10。用队列进行拓扑排序,将入度为0的顶点加入队列,再删除这些结点和其它结点之间的有向边,重复这一过程。在拓扑排序时,如果存在e=(u,v)的有向边,说明顶点v一定在u之后,让b[v]=b[u]+1,这样经过整个排序后就会得到一个符合要求的前缀和序列。

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

const int maxn = 15;

int n;
char s[maxn*maxn];
int b[maxn];
int inDegree[maxn];
int g[maxn][maxn];

void init() {
    memset(b, 0, sizeof(b));//把前缀和先全部初始化为0
    memset(inDegree, 0, sizeof(inDegree));
    memset(g, 0, sizeof(g));
}

void toposort() {
    queue<int> que;
    while (!que.empty()) que.pop();
    for (int i = 0; i <= n; ++i) {
        if (0 == inDegree[i]) que.push(i);
    }

    while (!que.empty()) {
        int u = que.front();
        que.pop();

        for (int i = 0; i <= n; ++i) {
            if (g[u][i] == 1) {
                b[i] = b[u] + 1;
                --inDegree[i];
                if (0 == inDegree[i]) que.push(i);
            }
        }
    }
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        init();
        scanf("%d%s", &n, s);
        for (int i = 1, k = 0; i <= n; ++i) {
            for (int j = i; j <= n; ++j) {
                if (s[k] == '+') {
                    g[i - 1][j] = 1;
                    ++inDegree[j];
                }
                else if (s[k] == '-') {
                    g[j][i - 1] = 1;
                    ++inDegree[i - 1];
                }
                ++k;
            }
        }
        toposort();
        for (int i = 1; i <= n; ++i) {
            printf("%d%c", b[i] - b[i - 1], i == n ? '\n' : ' ');
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值