zoukankan      html  css  js  c++  java
  • [CF286C] Main Sequence

    问题描述

    定义幸运数列:

    空数列是幸运数列

    如果 S 是幸运数列,那么 {r, S, -r} 也是幸运数列 (r > 0)

    如果 S 和 T 都是幸运数列,那么 {S, T} 也是幸运数列

    给定一个幸运数列中每个数的绝对值,并且要求其中的一些数是负数,其他的可正可负。

    问是否有合法方案,如果有,给出任意一种方案。 N ≤ 10^6

    幸运数列例子:{1, 2, -2, -1, 1, -1, 1, -1}

    输入:1 1 1 1 要求第三个数是负数 输出: 1 1 -1 -1

    样例输入

    2
    1 1
    0

    样例输出

    YES
    1 -1

    解析

    可以比较容易的看出来这是一个括号序列的形式。如果将正数视为左括号,负数视为右括号,那么给定一些数为负数就说明钦定了一些右括号,需要判断是否有满足要求的左括号。为了限定右括号,我们从右往左扫一遍,如果栈顶元素不等于当前元素或当前元素被指定为负数,就将元素入栈并标记为负数;否则弹出栈顶元素。最后如果栈不为空,说明无解;否则输出答案。

    代码

    #include <iostream>
    #include <cstdio>
    #define int long long
    #define N 1000002
    using namespace std;
    int n,m,i,a[N],q[N],s[N],top;
    bool f[N];
    int read()
    {
    	char c=getchar();
    	int w=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w;
    }
    signed main()
    {
    	n=read();
    	for(i=1;i<=n;i++) a[i]=read();
    	m=read();
    	for(i=1;i<=m;i++){
    		q[i]=read();
    		f[q[i]]=1;
    	}
    	for(i=n;i>=1;i--){
    		if(s[top]!=a[i]||f[i]) s[++top]=a[i],f[i]=1;
    		else top--;
    	}
    	if(top){
    		puts("NO");
    		return 0;
    	}
    	puts("YES");
    	for(i=1;i<=n;i++){
    		if(f[i]) printf("%lld ",-a[i]);
    		else printf("%lld ",a[i]);
    	}
    	puts("");
    	return 0;
    }
    

    反思

    若将原序列视为括号序列,则给定哪些数是负数就相当于钦定了一些右括号的位置。所以从右往左会比从左往右少写很多东西。还是要注意想好之后能否简化代码的写法,否则有可能会带来非常多的麻烦。

  • 相关阅读:
    最终作业
    第十二次作业
    Beta 冲刺(7/7)
    Beta 冲刺(6/7)
    Beta 冲刺(5/7)
    Beta 冲刺(4/7)
    Beta 冲刺(3/7)
    Beta 冲刺(2/7)
    Beta 冲刺(1/7)
    福大软工 · 第十次作业
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11745968.html
Copyright © 2011-2022 走看看