【2018.10.4】二连爆搜+再次出锅

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秒的时限 + 开氧气的条件下可以卡过。

至于空间,第一维是可以滚动的,所以省了第一维的空间。

posted @ 2018-10-04 14:54  大本营  阅读(412)  评论(0编辑  收藏  举报