cf301c Yaroslav and Algorithm

有一种程序,以一个字符串 \(a\) 为输入,包括一些操作。

  1. 每一次操作有两种,形如 \(s_i>>w_i\)\(s_i<>w_i\) ,其中 \(s_i,w_i\) 是长度不超过 \(7\) 的只包含数字和 ? 的字符串。
  2. 运行这个程序会多次按顺序遍历所有的操作。每次遍历会找到第一个操作 \(i\) 满足 \(s_i\)\(a\) 的子串并将 aa 中的第一个 \(s_i\) 替换成 \(w_i\)。如果找不到这样的操作,则程序停止。否则如果操作 \(i\) 是形如 \(s_i>>w_i\) 的,那么开始新一轮遍历,否则程序停止。
  3. 程序的输出就是程序停止时的 \(a\)

现在给出 \(n\) 个数 \(a_1,a_2,\ldots,a_n\) ,请你构造一个程序,要求对于每一个输入的 \(a_i\),输出 \(a_i+1\)

\(1\leq n\leq 100,\ a\leq 10^{25}\),操作数 \(\leq 50\) , 单个字符串操作次数 \(\leq 2000\)

思考,这个 \(100\) 个数可以以任何的形式出现,如果针对这 \(100\) 个数构造思考过一段时间后,发现没有什么前途 .

此时,考虑这个操作应该是具有通性的 . 对于任何 \(100\) 个数都可以得到想要的结果 .

如果要 \(+1\) ,分为进位和不进位两种,直接刚发现没有什么思路,那么,先思考不进位的怎么构造 .

很显然,可以直接让最后一个 \(2\to 3\) ,但是这有一个问题,我们只会找到第一个出现,怎么识别这是最后一个呢?

思考一会,发现仅仅依赖 09 是无法做到的,那么,就考虑 ? .

首先我考虑的是这些操作或许可以通过个数判别,但是发现无法支持只有 \(50\) 个操作这一条件 .

经过漫长的自闭,我发现,或许考虑类似于从前往后移动 ? 的位置,导致最后一位没有后继从而与其他位置区别开来,这个猜想很快得到了证实 .

对于不存在进位的 \(a\) , 可行的操作是

?0>>0?
?1>>1?
?2>>2?
?3>>3?
?4>>4?
?5>>5?
?6>>6?
?7>>7?
?8>>8?
?9>>9?
0?<>1
1?<>2
2?<>3
3?<>4
4?<>5
5?<>6
6?<>7
7?<>8
8?<>9
>>?

现在来考虑,加上进位的,此时,可以发现,\(9?\) 并没有具体的操作,是不是可以考虑改成 \(9?>>?0\) ,但是这会造成一个问题,操作就又会回到 \(?0>>0?\) 这个地方 . 但是,我们发现,? 的个数这个性质我们还没有利用过,使得分为两层,那么,很显然需要将前面的 \(1\)? 变成 \(2\)? .

操作就变成了

??0>>0??
??1>>1??
??2>>2??
??3>>3??
??4>>4??
??5>>5??
??6>>6??
??7>>7??
??8>>8??
??9>>9??
0??<>1
1??<>2
2??<>3
3??<>4
4??<>5
5??<>6
6??<>7
7??<>8
8??<>9
9??>>?0
9?>>?0
1?<>2
2?<>3
3?<>4
4?<>5
5?<>6
6?<>7
7?<>8
8?<>9
0?<>1
?<>1
>>??

此时一共 \(32\) 个操作,完全符合操作个数 .

时间复杂度 : \(O(1)\)

空间复杂度 : \(O(1)\)

posted @ 2022-02-04 09:58  xyangh  阅读(14)  评论(0)    收藏  举报