Codeforces550E:Brackets in Implications

Implication is a function of two logical arguments, its value is false if and only if the value of the first argument is true and the value of the second argument is false.

Implication is written by using character ‘‘,
and the arguments and the result of the implication are written as ‘0‘ (false)
and ‘1‘ (true). According to the
definition of the implication:

When a logical expression contains multiple implications, then when there are no brackets, it will be calculated from left to fight. For example,

.

When there are brackets, we first calculate the expression in brackets. For example,

.

For the given logical expression  determine
if it is possible to place there brackets so that the value of a logical expression is false. If it is possible, your task is to find such an arrangement of brackets.

Input

The first line contains integer n (1?≤?n?≤?100?000)
— the number of arguments in a logical expression.

The second line contains n numbers a1,?a2,?...,?an (),
which means the values of arguments in the expression in the order they occur.

Output

Print "NO" (without the quotes), if it is impossible to place brackets in the expression so that its value was equal to 0.

Otherwise, print "YES" in the first line and the logical expression with the required arrangement of brackets in the second line.

The expression should only contain characters ‘0‘, ‘1‘, ‘-‘
(character with ASCII code 45), ‘>‘ (character with ASCII code 62), ‘(‘
and ‘)‘. Characters ‘-‘ and ‘>‘
can occur in an expression only paired like that: ("->") and represent implication. The total number of logical arguments (i.e. digits ‘0‘
and ‘1‘) in the expression must be equal to n.
The order in which the digits follow in the expression from left to right must coincide with a1,?a2,?...,?an.

The expression should be correct. More formally, a correct expression is determined as follows:

  • Expressions "0", "1" (without
    the quotes) are correct.
  • If v1, v2 are
    correct, then v1->v2 is
    a correct expression.
  • If v is a correct expression, then (v) is
    a correct expression.

The total number of characters in the resulting expression mustn‘t exceed 106.

If there are multiple possible answers, you are allowed to print any of them.

Sample test(s)

input

4
0 1 1 0

output

YES
(((0)->1)->(1->0))

input

2
1 1

output

NO

input

1
0

output

YES
0


题意:
给出一个表达式的顺序,问我们能否通过添加一些括号来使得这个表达式最后变成0

思路:
首先我们要确定,表达式的最后必须是0,因为只有1->0才是0,
然后就是分情况讨论了
1.n-1是1,那么我们可以知道,根本不需要加括号,无论前面怎么计算,到了1的这个位置,都可以使得表达式为1,然后再与最后的0得到0

2.n-1是0的话,我们的目的就是使得前面n-1个数通过运算能得到1,首先对于n=3的特殊情况0 0 0,必然等得到0
然后n-1位是0,前面如果是1的话,我们必须都要先把这些连续的1全部先与这个0计算掉,否则我们知道,1在后面的话,无论前面计算的什么,再与1计算还是1,那么再与0计算就得到0了,最后再与末尾的0计算的话就得到1了,这样是不可行的,所以对于0前面连续的1我们要先与0计算掉,然后看现在所达到的位置。
如果位置都没有了,那么是不可行的了。
如果还没有超出界限,那么现在的这个位置必然是0,我们知道之前计算的连续的1与n-1的0计算得到的是0,那么我们只需要用这个位置的0,与刚刚计算的0计算,便可以得到1,那么现在我们又回到了第一种状况了,等于现在n-1位已经变成1了,那么只需要在这个过程中打上括号即可

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;

#define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 2000005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8

int n;
int a[100005];

int main()
{
    int i,j,k;
    while(~scanf("%d",&n))
    {
        for(i = 1; i<=n; i++)
            scanf("%d",&a[i]);
        //   printf("---\n");
        if(a[n]==1)
        {
            printf("NO\n");
            continue;
        }
        if(n==1)
        {
            if(a[1] == 0)
                printf("YES\n0\n");
            else
                printf("NO\n");
            continue;
        }
        if(n==2)
        {
            if(a[1]==1&&a[2]==0)
                printf("YES\n%d->%d\n",a[1],a[2]);
            else
                printf("NO\n");
            continue;
        }
        if(a[n-1]==1)
        {
            printf("YES\n");
            printf("%d",a[1]);
            for(i = 2; i<=n; i++)
                printf("->%d",a[i]);
            printf("\n");
            continue;
        }
        else
        {
            if(n==3 && a[n-2]==0)// 0 0 0可行
            {
                printf("YES\n");
                printf("%d",a[1]);
                for(i = 2; i<=n; i++)
                    printf("->%d",a[i]);
                printf("\n");
                continue;
            }
            for(i = n-2; i>=0&&a[i]==1; i--);
            int pos = i;//找到非连续1的第一个0的位置
            if(pos == 0)//全部是1的话不行
            {
                printf("NO\n");
                continue;
            }
            printf("YES\n");
            for(i = 1; i<=pos-1; i++)
            {
                printf("%d->",a[i]);
            }
            printf("(%d->",a[pos]);//先给0上一个括号
            printf("(");
            for(i = pos+1; i<=n-1; i++)//给n-1和n-1前面连续的1上一个括号
            {
                printf("%d",a[i]);
                if(i == n-1)
                    printf("))");
                printf("->");
            }
            printf("%d\n",a[n]);
        }
    }

    return 0;
}

时间: 2024-10-12 07:37:24

Codeforces550E:Brackets in Implications的相关文章

CodeForces 550E Brackets in Implications(构造)

[题目链接]:click here~~ [题目大意]给定一个逻辑运算符号a->b:当前仅当a为1b为0值为0,其余为1,构造括号.改变运算优先级使得最后结果为0 [解题思路]: todo~~ /* 思路: 1.假设最后一位是1,不管怎样结果不会为0.puts("NO"); 2.那么有解的情况下最后一位必为0 2.1.进一步发现,事实上倒数第二位必为1,仅仅有1前面的结果和该位1结合才干等于1,进一步1->0=0; 2.2.假设1前面是0.那么合并这两位数,组成1,递推2.1

codeforces #550E Brackets in Implications 构造

题目大意:定义在集合{0,1}上的运算符"→",定义如下: 0→0=1 0→1=1 1→0=0 1→1=1 现在给定一个表达式a1→a2→a3→...→an,要求添加一些括号使得值为0 由于0=1→0,因此显然末尾必须是0,否则无解 然后我们这么构造: (a1→(a2→(a3→(...))))→an 由于an=0,所以前面的那些东西必须等于1 然后我们讨论an?1 如果an?1=1,那么前面那坨东西显然是1(因为0要求末尾是0) 如果an?1=0,那么找到前面第一个0,一直合成到这个0

「日常训练」Brackets in Implications(Codeforces Round 306 Div.2 E)

题意与分析 稍微复杂一些的思维题.反正这场全是思维题,就一道暴力水题(B). 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back #define fi first #define se second #define ZERO(x) memset((x), 0, sizeof(x)) #define ALL(x) (x).begin(),(x).end() #define rep(i, a, b) fo

XJTU Summer Holiday Test 1(Brackets in Implications-构造)

B - Brackets in Implications Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Description Implication is a function of two logical arguments, its value is false if and only if the value of the first argument is true and t

Codeforces Round #306 (Div. 2) (ABCE题解)

比赛链接:http://codeforces.com/contest/550 A. Two Substrings time limit per test 2 seconds memory limit per test 256 megabytes You are given string s. Your task is to determine if the given string s contains two non-overlapping substrings "AB" and &

Codeforces Round #306 (Div. 2) D.E. 解题报告

D题:Regular Bridge 乱搞.构造 这题乱搞一下就行了.构造一个有桥而且每个点的度数都为k的无向图.方法很多,也不好叙述.. 代码如下: #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <map> #include <algorithm> #define INF 0x

Codeforces Round #306 (Div. 2) (构造)

A. Two Substrings 题意:给一个字符串,求是否含有不重叠的子串"AB"和"BA",长度1e5. 题解:看起来很简单,但是一直错,各种考虑不周全,最后只能很蠢的暴力,把所有的AB和BA的位置求出来,能有一对AB和BA不重叠即可. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 char a[100005]; 5 vector<int> ab; 6 vector<i

CF149D. Coloring Brackets[区间DP !]

不知道为什么居中了,先把代码放这 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N=705,MOD=1e9+7; char s[N]; long long n,f[N][N][5][5]; int st[N],top=0,m[N]; void match(){ for(int i=1;i<=

POJ 2955 Brackets (动规)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2999   Accepted: 1536 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg