#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')*
运算优先级与通常算术规则一致:
- 三种括号中的表达式优先级最高;
- 乘法优先于加法和减法;
- 相同优先级的运算从左到右计算。
相关字符的 ASCII 码如下:
| 字符 | ( |
) |
* |
+ |
- |
0~9 |
= |
A~Z |
[ |
] |
a~z |
{ |
} |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ASCII | 40 | 41 | 42 | 43 | 45 | 48~57 | 61 | 65~90 | 91 | 93 | 97~122 | 123 | 125 |
你的任务是编写一个拆分模块,把每个密码表示成若干正确算术等式逐字符 ASCII 异或的结果。
输入格式
第一行包含一个整数 ,表示需要拆分的密码数量:
接下来 行,每行包含一个密码字符串 :
密码只包含数字、小写英文字母和大写英文字母。
输出格式
对每个密码分别输出答案。
如果不存在合法拆分,输出:
NO
否则先输出:
YES
下一行输出一个整数 :
表示拆分中算术等式的数量。
接下来 行,每行输出一条正确的算术等式。每条等式的长度都必须与当前密码相同,并满足逐字符 ASCII 异或条件。
可以证明:只要有解,就一定存在一个 的解。
样例
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)