T1:五子棋
【题目描述】
五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。
五子连珠是在 横线,纵线,斜线,反斜线 四个方向上形成五子及以上的连线,当出现多于五子的连珠时,也只记为一次五子连珠。
五子连珠总数. 等于棋局中的所有方向上的五子连珠连线的数量之和。我们想知道,给定一个长宽皆为 n 的棋局,白棋落在哪些点可以增加白棋五子连珠总数?对增加白棋五子连珠总数的举例说明 (A 点为我们选择的落点):
1 wwwwAbbbb
落白棋之前未形成五子连珠,落入白棋之后,五子连珠总数加一,满足要求。
2 wwwwwAbbbb
落白棋之前已经形成五子连珠,落白棋之后,五子连珠总数不变,不满足要求。
3 wwwwwAwwwww
落白棋之前五子连珠总数为二,落入白棋之后,两边连成一线,五子连珠总数减一,不满足要求。
4
*w***w*****
**w**w*****
***w*w*****
****ww*****
wwwwwAwwwww
落白棋之前五子连珠总数为二。落入白棋之后,两边连成一线,斜向和纵向形成新的五子连珠,总数为三。五子连珠总数加一,这个点满足要求。
【输入格式】
从文件 wuzi.in 中读入数据。输入为第一行为一个数字 n(n ≤ 40),表示棋盘大小。接下来的 n 行,每行为 n 个字符,可能有三种字符,*表示无棋子,b表示黑棋,
w表示白棋。输入棋局中可能已经有五子连珠的情况,我们需要计算能增加白棋五子连珠总数的白棋落点。
【输出格式】
输出到文件 wuzi.out 中。输出为 k 行,包括 k 个满足要求的落点,k 个点按照从左至右,从上至下的顺序输出,即先按行排序,再按列排序输出。
每行为一个点坐标 $(x,y)$,分别表示列坐标,行坐标,以空格分隔,坐标序号从0开始,棋盘左上角为原点。
*a***
*****
*****
*****
***b*
图中 a 点的坐标为 $(1,0)$,b 点的坐标为 $(3,4)$。
【样例输入】
8
****b*bb
*****b*b
bb*bbbw*
w*wbwwww
bwwbwwbw
ww**wbbw
*bww***w
***bwb*b
【样例输出】
7 2
2 5
3 5
4 6
2 7
【子任务】
共20组数据
1,2 没有满足要求的点
3,4,5,6,7,8 只需要计算横纵方向, 棋局中不存在旧的五子连珠
9,10,11,12,13,14 需要计算所有方向, 棋局中不存在旧的五子连珠
15,16,17,18,19,20 盘面上存在旧的五子连珠
只考虑中间隔一个点的连棋,所以直接爆搜,判各个方向的情况。
T2:Equation
【题目描述】
给定一个等式,其格式为 $p ◦ q = r$,其中 $1≤ p,q,r < 10^9$,算符 ◦ 可以是 +、- 或 *(表示乘法)。
$p$,$q$ 和 $r$ 中的某些数字被替换成了大写字母,例如 $A09+ C0B = 6AC$。你的任务是找出所有大写字母代表的数字,使得等式成立。
你需要遵循下列规则:
1. 相同的字母替换成相同的数字,不同的字母替换成不同的数字。
2. $p$、$q$ 和 $r$ 不能以$0$开头。称两个方案不同,如果存在一个字母被替换成了不同的数字。考虑到方案数可能很多,你只需要输出合法方案的数量。注意如果没有方法使得等式成立,你应该输出$0$。
【输入格式】
从文件 equation.in 中读入数据。
输入只有一行,表示需要处理的等式。保证最多只有9个不同的字母,等式中不会出现空格。
【输出格式】
输出到文件 equation.out 中。
输出一个整数,表示方案的数量。
【样例1输入】
A09+C0B=6AC
【样例1输出】
1
【样例1解释】
唯一合法的方案是109+506=615。
【样例2输入】
P*Q=P
【样例2输出】
8
【样例3输入】
CANADA-MAR8=CCC
【样例3输出】
0
【子任务】
总共有 10 个测试点。
对于测试点1∼3,等式中最多有3个不同的字母。
对于测试点1、2、4、7和8,◦ 只可能是 + 或 -。
对于测试点1、4、5和6,每个字母只会出现一次。
先特判一下,超过10个字母,方案数直接是0。
那对于最多10个字母,由于每个字母只代表一个数且不同的字母代表的数不相同,所以枚举每个字母的取值,方案数是$10!=3628800$。
于是写个合格的搜索就过了……
T3:增加代码长度(原题的红字部分描述有问题,此处修正)
【题目描述】
++C 语言是 C++ 语言的一种变体,这种语言给 C++ 添加了很多的功能。其中一 个实用的功能是注释嵌套,任意的 /* 和 */ 组成的括号可以互相嵌套,即 /*/*a*/*/ 是一段合法的代码。
你已经用 ++C 写了一份代码,但你的公司是根据代码的长度计算你的工作量的, 因此你希望在代码的末尾加上一段“纯注释”,以此增加你的代码长度。
以下是 纯注释 的形式化定义:
• 空串是纯注释
• 在 /* 和 */ 中间仅包含若干个纯注释和小写字母的串(可以没有小写字母)是纯注释
• 如果 s 和 t 都是纯注释,那么 st 是纯注释
现在你手里有一段长度为 n 的代码,其中有若干个位置已经确定,必须填写给定的字符;有些位置可以由你自由设置,用 $?$ 表示。 你希望将它改成纯注释并多次提交它。但为了防止被系统查出,你希望每次提交不同的纯注释。因此你想要知道有多少种不 同的设置自由位置的方式。为了避免高精度运算,请输出答案除以 $10^9 + 7$ 的余数。 注意,一种可能发生的情况是,任何设置自由位置的方式都不能得到纯注释,对于这种情况请输出 $0$。
【输入格式】
从文件 code.in 中读入数据。 输入文件包含多组数据,每一行都是一组数据,直到文件末尾结束。 每组数据仅一行一个长度为 n 的仅包含 $/$、$*$、$?$ 和小写字母的字符串。
【输出格式】
输出到文件 code.out 中。 对于每一组数据,输出所有可以通过将 ? 替换为其他字符得到的不同纯注释字符 串的个数除以 $10^9 + 7$ 的余数。
【样例 1 输入】
/*?*/
【样例 1 输出】
26
【样例 1 解释】
? 可以换成任意小写字母。
【样例 2 输入】
?
??
???
????
?????
??????
???????
????????
【样例 2 输出】
0
0
0
1
26
676
17576
456978
【子任务】
对于 20% 的数据,输入不包含 $?$;
对于另外 30% 的数据,输入的 $?$ 不超过 8 个;
对于前 70% 的数据,$n≤1000$;
对于所有数据,数据组数 $≤10$,$n≤2×10^4$。
按照出题人的意思,写个我们都熟悉的括号匹配dp就完了。
$dp[i][j]$表示到从第$1$到$i$位中,还有$j$个左括号还没被右括号匹配掉时的填空方案数。最终正确的注释是 处理完所有位 且 左右括号完全匹配的,所以结果是$dp[n][0]$。
由于左、右括号都是注释,占两位,再加上要让最终所有左右括号匹配,最多只可能有$n/2/2 = n/4 = 5000$个左括号。所以时间复杂度是$O(n*frac{n}{4})$的,最多$20000*5000=10^8$,在3秒的时限 + 开氧气的条件下可以卡过。
至于空间,第一维是可以滚动的,所以省了第一维的空间。