[2019牛客多校训练第3场]Median

链接:https://ac.nowcoder.com/acm/contest/883/I
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K

Special Judge, 64bit IO Format: %lld
分数:2500
题目描述
JSB has an integer sequence a 1 , a 2 , , a n a_1, a_2, \dots, a_n ​. He wants to play a game with SHB.

For each 1 i n 2 1 \le i \le n-2 , JSB calculates the median of { a i , a i + 1 , a i + 2 } \{a_i, a_{i+1}, a_{i+2}\} , denoted by bib_ibi​. SHB is given the sequence b 1 , b 2 , , b n 2 b_1, b_2, \dots, b_{n-2} ​. Can you help him restore the sequence a a ?

Recall that the median of three numbers is the second largest one of them.

输入描述:

There are multiple cases. The first line of the input contains a single positive integer T T , indicating the number of cases.

For each case, the first line of the input contains a single integer n   ( 3 n 1 0 5 ) n n\ (3 \le n \le 10^5)n , the length of the sequence a\ a a. The second line contains   n 2 \ n-2 integers b 1 , b 2 , , b n 2   ( 0 b i 1 0 9 ) b_1, b_2, \dots, b_{n-2}\ (0 \le b_i \le 10^9) .

It’s guaranteed that the sum of n n over all cases does not exceed 1 0 6 10^6 .

输出描述:
For each case print one line containing n n integers, indicating the sequence a 1 , a 2 , , a n a_1, a_2, \dots, a_n . Your output must satisfy 0 a i 1 0 9 0 \le a_i \le 10^9 for each 1 i n 1 \le i \le n .

If there are multiple valid answers, you may print any of them. If there is no valid answer, print"-1" (without quotes) instead.

示例1
输入

4
5
1 2 3
6
1 2 3 4
6
1 2 4 3
6
1 3 4 2

输出

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

题意:
给定 b [ 1 ] , b [ 2 ] b [ n 2 ] b[1],b[2] \dots b[n-2] b [ i ] b[i] 表示 a [ i ] , a [ i + 1 ] , a [ i + 2 ] {a[i],a[i+1],a[i+2]} 的中位数。要求构造出符合条件的序列 { a n } \{a_n\} ,无解输出 1 -1

题解:
先考虑判定问题。很显然跟一个 a [ i ] a[i] 有关的中位数 b [ i ] b[i] 最多只有3个 b [ i 2 ] , b [ i 1 ] , b [ i ] b[i-2],b[i-1],b[i]
f [ i ] [ j ] [ k ] f[i][j][k] 表示当前第 i i 个位置取跟自己有关的第 j + 1 j+1 个中位数,第 i 1 i-1 个位置取跟其有关的第 k + 1 k+1 个中位数,这样就可以通过查看 f [ i 1 ] [ k ] [ l ] f[i-1][k][l] 的值并且判定一下这三个数的中位数能否等于 b [ i 1 ] b[i-1] 即可。
然后答案的话可以通过记录 p r e [ i ] [ j ] [ k ] pre[i][j][k] 表示转移前项,来搞定。

#include<bits/stdc++.h>
#define ll long long
#define INF 1999122700
using namespace std;
int n,b[100004];
int vec[100004][3];
int pre[100004][3][3];
bool f[100004][3][3];

bool check(int ti,int j,int k,int l){
    int s[4]={vec[ti][j],vec[ti-1][k],vec[ti-2][l]};
    sort(s,s+3);
    return (s[1]==b[ti-1]);
}
void print(int t,int j,int k){
    if(t==1){
        printf("%d ",vec[t][j]);
        return ;
    }
    print(t-1,k,pre[t][j][k]);
    printf("%d",vec[t][j]);
    if(t==n){
        puts("");
    }
    else{
        printf(" ");
    }
}
int w33ha(){
    scanf("%d",&n);
    for(int i=2;i<n;i++)scanf("%d",&b[i]);
    for(int i=1;i<=n;i++){
        for(int j=0;j<3;j++){
            for(int k=0;k<3;k++){
                f[i][j][k]=0;
            }
        }
    }
    b[n]=b[n-1];b[n+1]=b[n-1];
    b[1]=b[2];b[0]=b[2];
    for(int i=1;i<=n;i++){
        vec[i][0]=b[i-1];
        vec[i][1]=b[i];
        vec[i][2]=b[i+1];
        sort(vec[i],vec[i]+3);
    }
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            f[1][i][j]=1;
            f[2][i][j]=1;
        }
    }
    for(int i=3;i<=n;i++){
        for(int j=0;j<3;j++){
            for(int k=0;k<3;k++){
                for(int l=0;l<3;l++){
                    if(!f[i-1][k][l])continue;
                    if(check(i,j,k,l)){
                        f[i][j][k]=1;
                        pre[i][j][k]=l;
                    }
                }
            }
        }
    }
    bool flag=0;
    for(int j=0;j<3;j++){
        for(int k=0;k<3;k++){
            if(f[n][j][k]){
                flag=1;
                print(n,j,k);
                break;
            }
        }
        if(flag)break;
    }
    if(!flag)puts("-1");
    return 0;
}
int main(){
    int T;scanf("%d",&T);
    while(T--)w33ha();
    return 0;
}

发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/99604324
今日推荐