UvaLive4255 Guess

UvaLive 4255 Guess

题意:给你一个上三角矩阵S。S[i][j]取值为‘+’‘-’‘0’。表示序列的和从num[i]+...+num[j]的取值分别为正负0。

思路:把前缀和看做点。把矩阵的正负看做点之间的边。然后对这些点进行拓扑排序。要注意的是取值为0的特殊情况。

/*
ID: onlyazh1
LANG: C++
TASK: Guess
*/
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
#include<cctype>
#include<vector>
#include<cstring>
#include<fstream>
#include<iomanip>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;

const int maxn=30;
int n;
int sum[maxn];
int deg[maxn];
vector<int> G[maxn];

void TopSort(){
    int low=-10;
    queue<int> Que;
    for(int i=0;i<=n;i++)
        if(!deg[i]) Que.push(i);
    while(!Que.empty()){
        int x=Que.front();
        Que.pop();
        sum[x]=low;
        for(int u=0,sz=G[x].size();u<sz;u++){
            deg[G[x][u]]--;
            if(!deg[G[x][u]])
                Que.push(G[x][u]);
        }
        low++;
    }
}
int main(){
    ifstream cin("in.txt");
    int T;cin>>T;
    while(T--){

        for(int i=0;i<maxn;i++)
            G[i].clear();
        memset(deg,0,sizeof(deg));

        int cnt=0;cin>>n;
        char str[maxn];cin>>str;
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++){
                if(str[cnt]=='-'){
                    G[j].push_back(i-1);
                    deg[i-1]++;
                }
                else if(str[cnt]=='+'){
                    G[i-1].push_back(j);
                    deg[j]++;
                }
                cnt++;
            }
        TopSort();
        cnt=0;
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++){
                if(str[cnt]=='0')
                    sum[i-1]=sum[j];
                cnt++;
            }
        for(int i=1;i<=n;i++){
            if(i-1) cout<<" ";
            cout<<sum[i]-sum[i-1];
        }
        cout<<endl;
    }
    return 0;
}
View Code

 

posted on 2016-02-23 12:12  onlyAzha  阅读(204)  评论(0编辑  收藏  举报

导航