#P16846. [NWRRC 2020]Joint Password Storage

[NWRRC 2020]Joint Password Storage

题目描述

Johnny 是 Joint Password Storage(JPS,联合密码存储)的开发者。把密码以明文形式保存显然不是一个好主意,因此 JPS 会把每个密码拆成若干部分并分别存储。

密码是一个只包含数字和英文字母的字符串。所有部分逐字符进行按位异或后,必须恰好得到原密码。

为了不引人注意,Johnny 希望每一部分看起来都很普通,例如一条算术等式。还有什么能比 2+2=4 更普通呢?

形式化地说,一个合法拆分由若干条正确的算术等式组成,所有等式的长度都与密码长度相同。对于密码的每一个位置,把所有等式在该位置上的字符 ASCII 码按位异或,结果必须等于密码对应字符的 ASCII 码。

一条正确的算术等式由下面的文法描述,并且等号左右两个表达式的值必须相等:

<equality>   ::= <expression> '=' <expression>
<expression> ::= <term>
               | <expression> '+' <term>
               | <expression> '-' <term>
<term>       ::= <multiplier>
               | <term> '*' <multiplier>
<multiplier> ::= <number>
               | '(' <expression> ')'
               | '[' <expression> ']'
               | '{' <expression> '}'
<number>     ::= '0'
               | ('1' | ... | '9') ('0' | ... | '9')*

运算优先级与通常算术规则一致:

  1. 三种括号中的表达式优先级最高;
  2. 乘法优先于加法和减法;
  3. 相同优先级的运算从左到右计算。

相关字符的 ASCII 码如下:

字符 ( ) * + - 09 = AZ [ ] az { }
ASCII 40 41 42 43 45 48~57 61 65~90 91 93 97~122 123 125

你的任务是编写一个拆分模块,把每个密码表示成若干正确算术等式逐字符 ASCII 异或的结果。

输入格式

第一行包含一个整数 PP,表示需要拆分的密码数量:

1P50.1\le P\le 50.

接下来 PP 行,每行包含一个密码字符串 ss

10s50.10\le |s|\le 50.

密码只包含数字、小写英文字母和大写英文字母。

输出格式

对每个密码分别输出答案。

如果不存在合法拆分,输出:

NO

否则先输出:

YES

下一行输出一个整数 kk

1k1000,1\le k\le 1000,

表示拆分中算术等式的数量。

接下来 kk 行,每行输出一条正确的算术等式。每条等式的长度都必须与当前密码相同,并满足逐字符 ASCII 异或条件。

可以证明:只要有解,就一定存在一个 k1000k\le 1000 的解。

样例

3
1915090454
CanIAlwaysSplitIt
2020NorthwesternRussiaRegionalContestTaskJ
YES
3
9+91*9=828
1+19+0=4*5
999=1008-9
NO
YES
7
420+[1*2*3*4*5*6]=140+[1*10*1*[20-5-5]*10]
10-1-{1}-{1}-{1}-{1}={1}+{1}+{1}+{{1}+{1}}
739=1+{3}*{2}*{9}*{9}-3+{2}*7*11*1+{100}+1
602211592866240={54321*67890}*9*{8*7*6*54}
51-188*1*0*600198090+5=[0]*(1039-25-4)+8*7
0*990-5127*11590*740*0*[3]*90=8*0*4885*2*8
3*0-0*818*39=0*(6+10*(64))*200*(93+6+8+19)