#P16487. PM2246数字统计表

PM2246数字统计表

背景故事

某市实验小学的数学老师王老师在批改作业时,发现班长李明写了一句特别的话:

"这句话里有 10213223。"

王老师仔细一看,惊讶地发现这句话竟然准确描述了自己内部每个阿拉伯数字出现的次数! 句子中确实有 1 个 0、2 个 1、3 个 2 和 2 个 3。王老师把这种句子称为自描述句,并给全班布置了一项挑战:给定某些数字的固定出现次数,补全其余数字的出现次数,构造出一个合法的自描述句。

题目描述

一个自描述句必须满足以下规则:

  1. 句子会统计自身中出现的每个数字(0099)的出现次数。
  2. 对于在句子中出现的数字,必须恰好给出一次准确的计数;不能重复给出同一个数字的计数,也不能遗漏。
  3. 句子中出现的所有数字不允许有前导零(例如不能写成 "02")。

现在给定一个长度为 1010 的数组 counts[0..9]counts[0..9],其中 counts[d]counts[d] 表示对数字 dd 的约束:

  • counts[d]=1counts[d] = -1,表示数字 dd 的出现次数可以是任意非负整数(包括 00,即 dd 可以不出现在句子中)。
  • counts[d]0counts[d] \ge 0,表示数字 dd 的出现次数必须恰好等于 counts[d]counts[d]00 意味着 dd 不能出现在句子中)。

请你求出一个满足所有约束的自描述句对应的实际出现次数数组。如果存在多个解,选择字典序最小的那个(即先让 counts[0]counts[0] 尽量小,若相同则让 counts[1]counts[1] 尽量小,以此类推)。如果不存在满足条件的自描述句,则输出空数组。

输入格式

一行 1010 个整数,依次为 counts[0],counts[1],,counts[9]counts[0], counts[1], \dots, counts[9]

输出格式

  • 若不存在满足条件的自描述句,输出一行一个整数 00
  • 若存在,第一行输出整数 1010,第二行输出 1010 个整数,表示字典序最小的合法出现次数数组 c[0..9]c[0..9]

样例

样例 1

输入

1 -1 -1 -1 -1 -1 -1 -1 -1 -1

输出

10
1 2 3 2 0 0 0 0 0 0

解释:要求数字 00 恰好出现 11 次。一个合法的自描述句为:

"这句话里有 1 个 0,2 个 1,3 个 2,2 个 3。"

样例 2

输入

100 -1 -1 -1 -1 -1 -1 -1 -1 -1

输出

0

解释:不可能构造出自描述句让数字 00 出现 100100 次。

样例 3

输入

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1

输出

10
0 0 0 0 0 0 0 0 0 0

解释:所有数字都可以不出现。退化的自描述句如 "这句话是空的。" 其中不含任何数字。

数据范围

  • countscounts 恰好包含 1010 个元素。
  • 每个元素满足 1counts[i]100-1 \le counts[i] \le 100

难度评定

  • 关键观察:需要发现自描述句中出现的数字仅来源于两部分——各数字的计数本身,以及 "数字 dd 出现了 c[d]c[d] 次" 这句话里显式写出的被计数数字 dd。文本模板本身不含任何数字。
  • 建模:将问题转化为一个关于 1010 个变量的自指方程组 $c[d] = \text{freq}_d(\{c[i] \mid c[i]>0\}) + [c[d]>0]$。
  • 算法知识:深度优先搜索配合多重剪枝(和约束、forbid 集合、需求-供给分析)。
  • 证明:通过和式分析严格证明所有合法解中 c[i]40\sum c[i] \le 40,进而得到每个 c[i]21c[i] \le 21,从而将搜索空间限制在可接受的范围内。
  • 实现:需要精细地维护当前频率、forbid 集合,并在 DFS 中做需求-供给剪枝;同时注意退化情况(全零解)和字典序最小的处理。
  • 边界:全零退化情况、固定值大于理论上限导致无解、固定值为 00 时对 forbid 集合的连锁影响。

Codeforces 参考评分:约 2200。