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 v1v2 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;
}


你可能感兴趣的:(codeforces)