Skip to content

Commit 0af2955

Browse files
committed
灵茶の试炼 * 61 (无UT)
1 parent ecfbdd0 commit 0af2955

File tree

64 files changed

+7703
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+7703
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package c359;
2+
3+
import java.util.Arrays;
4+
import java.util.Scanner;
5+
6+
public class Abc359_d {
7+
static int n, k;
8+
static char[] s;
9+
10+
public static void main(String[] args) {
11+
Scanner scanner = new Scanner(System.in);
12+
n = scanner.nextInt();
13+
k = scanner.nextInt();
14+
s = scanner.next().toCharArray();
15+
System.out.println(solve());
16+
}
17+
18+
private static final int MOD = 998244353;
19+
static boolean[] pal;
20+
static int mask;
21+
static long[][] memo;
22+
23+
private static String solve() {
24+
pal = new boolean[1 << k];
25+
o:
26+
for (int i = 0; i < pal.length; i++) {
27+
for (int j = 0; j < k / 2; j++) {
28+
if ((i >> j & 1) != (i >> (k - 1 - j) & 1)) {
29+
continue o;
30+
}
31+
}
32+
pal[i] = true;
33+
}
34+
35+
mask = (1 << (k - 1)) - 1;
36+
memo = new long[n][1 << k];
37+
for (int i = 0; i < n; i++) {
38+
Arrays.fill(memo[i], -1);
39+
}
40+
return String.valueOf(dfs(n - 1, 0));
41+
}
42+
43+
static long dfs(int i, int j) {
44+
if (i < 0) {
45+
return 1;
46+
}
47+
if (memo[i][j] != -1) return memo[i][j];
48+
long res = 0;
49+
for (int b = 0; b < 2; b++) {
50+
if (s[i] != '?' && (s[i] & 1) != b) {
51+
continue;
52+
}
53+
int t = j << 1 | b;
54+
if (i > n - k || !pal[t]) {
55+
res += dfs(i - 1, t & mask);
56+
}
57+
}
58+
return memo[i][j] = res % MOD;
59+
}
60+
}
61+
/*
62+
D - Avoid K Palindrome
63+
https://atcoder.jp/contests/abc359/tasks/abc359_d
64+
65+
灵茶の试炼 2024-08-06
66+
题目大意:
67+
输入 n k(2≤k≤n≤1000 且 k≤10) 和长为 n 的字符串 s,只包含 A,B,? 三种字符。
68+
如果一个字符串不包含长度恰好为 k 的回文子串,我们称其为合法字符串。
69+
把 s 中的所有 ? 替换成 A 或 B,可以得到 2^q 个不同的字符串,其中 q 是 s 中的 ? 的个数。
70+
输出这 2^q 个字符串中的合法字符串个数,模 998244353。
71+
72+
把 AB 信息用二进制压缩表示。
73+
下面的写法中,二进制高位对应的字母在 s 中更靠右的位置,二进制低位对应的字母在 s 中更靠左的位置。
74+
从右往左递归。
75+
定义 dfs(i,j),其中 i 右边的 k-1 个字母的二进制为 j,计算替换 s[0] 到 s[i] 中的 ?,能得到多少个合法子串。
76+
枚举 b=0,1(如果 s[i]!=? 则 b=s[i]&1)。
77+
把 b 和 j 拼起来,即 t = j<<1 | b,如果 i>n-k,或者得到的二进制数 t 不是回文的,那么就递归到 dfs(i-1, t&mask),其中 mask = (1 << (k-1)) - 1,用来去掉二进制的最高位。
78+
递归边界:dfs(-1,j)=1,表示找到了一个合法字符串。
79+
递归入口:dfs(n-1,0)。
80+
记忆化搜索 https://atcoder.jp/contests/abc359/submissions/56382758
81+
1:1 翻译成递推 https://atcoder.jp/contests/abc359/submissions/56382174
82+
======
83+
84+
Input 1
85+
7 4
86+
AB?A?BA
87+
Output 1
88+
1
89+
90+
Input 2
91+
40 7
92+
????????????????????????????????????????
93+
Output 2
94+
116295436
95+
96+
Input 3
97+
15 5
98+
ABABA??????????
99+
Output 3
100+
0
101+
*/
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package c377;
2+
3+
import java.util.Scanner;
4+
5+
public class Abc377_a {
6+
static char[] s;
7+
8+
public static void main(String[] args) {
9+
Scanner scanner = new Scanner(System.in);
10+
s = scanner.next().toCharArray();
11+
System.out.println(solve());
12+
}
13+
14+
private static String solve() {
15+
int mask = 0;
16+
for (char c : s) {
17+
mask |= 1 << (c - 'A');
18+
}
19+
int ans = (mask & 0b111);
20+
return ans == 0b111 ? "Yes" : "No";
21+
}
22+
}
23+
/*
24+
A - Rearranging ABC
25+
https://atcoder.jp/contests/abc377/tasks/abc377_a
26+
27+
题目大意:
28+
给你一个长度为 $3$ 的字符串 $S$ ,由大写英文字母组成。
29+
请判断是否有可能重新排列 $S$ 中的字符,使其与字符串 `ABC` 匹配。
30+
31+
bitmask 判断。
32+
======
33+
34+
Input 1
35+
BAC
36+
Output 1
37+
Yes
38+
39+
Input 2
40+
AAC
41+
Output 2
42+
No
43+
44+
Input 3
45+
ABC
46+
Output 3
47+
Yes
48+
49+
Input 4
50+
ARC
51+
Output 4
52+
No
53+
*/
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package c377;
2+
3+
import java.util.Scanner;
4+
5+
public class Abc377_b {
6+
static char[][] a;
7+
8+
public static void main(String[] args) {
9+
Scanner scanner = new Scanner(System.in);
10+
a = new char[8][];
11+
for (int i = 0; i < 8; i++) {
12+
a[i] = scanner.next().toCharArray();
13+
}
14+
System.out.println(solve());
15+
}
16+
17+
private static String solve() {
18+
boolean[] row = new boolean[8];
19+
boolean[] col = new boolean[8];
20+
for (int i = 0; i < 8; i++) {
21+
for (int j = 0; j < 8; j++) {
22+
if (a[i][j] == '#') {
23+
row[i] = true;
24+
col[j] = true;
25+
}
26+
}
27+
}
28+
29+
int ans = 0;
30+
for (int i = 0; i < 8; i++) {
31+
for (int j = 0; j < 8; j++) {
32+
if (!row[i] && !col[j]) ans++;
33+
}
34+
}
35+
return String.valueOf(ans);
36+
}
37+
}
38+
/*
39+
B - Avoid Rook Attack
40+
https://atcoder.jp/contests/abc377/tasks/abc377_b
41+
42+
题目大意:
43+
有一个由 $64$ 个正方形组成的网格,网格中有 $8$ 行和 $8$ 列。让 $(i,j)$ 表示从上面 $(1\leq i\leq8)$ 起第 $i$ 行,从左边 $(1\leq j\leq8)$ 起第 $j$ 列的正方形。
44+
每个方格要么是空的,要么有棋子放在上面。方格的状态由长度为 $8$ 的 $8$ 字符串序列 $(S_1,S_2,S_3,\ldots,S_8)$ 表示。方格 $(i,j)$ 如果 $S_i$ 的 $j$ -th 字符是 `.`,则 $(1\leq i\leq8,1\leq j\leq8)$ 为空;如果是 `#`,则有棋子。
45+
您要将棋子放在**空位**上,使它**不能被任何现有棋子吃掉**。
46+
放置在位置 $(i,j)$ 上的棋子可以吃掉满足以下任一条件的棋子:
47+
- 放置在 $i$ 行的一个位置上
48+
- 放置在 $j$ 列的一个位置上
49+
例如,位于 $(4,4)$ 位置上的棋子可以吃掉位于下图中蓝色所示位置上的棋子:
50+
您可以将棋子放在几个位置上?
51+
52+
分别记录行列。
53+
======
54+
55+
Input 1
56+
...#....
57+
#.......
58+
.......#
59+
....#...
60+
.#......
61+
........
62+
........
63+
..#.....
64+
Output 1
65+
4
66+
67+
Input 2
68+
........
69+
........
70+
........
71+
........
72+
........
73+
........
74+
........
75+
........
76+
Output 2
77+
64
78+
79+
Input 3
80+
.#......
81+
..#..#..
82+
....#...
83+
........
84+
..#....#
85+
........
86+
...#....
87+
....#...
88+
Output 3
89+
4
90+
*/
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package c377;
2+
3+
import java.util.HashSet;
4+
import java.util.Scanner;
5+
import java.util.Set;
6+
7+
public class Abc377_c {
8+
static Scanner scanner = new Scanner(System.in);
9+
static long n, m;
10+
11+
public static void main(String[] args) {
12+
n = scanner.nextInt();
13+
m = scanner.nextInt();
14+
System.out.println(solve());
15+
}
16+
17+
private static final int[][] DIRECTIONS = {{-2, -1}, {-2, 1}, {2, -1}, {2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}};
18+
19+
private static String solve() {
20+
Set<Long> set = new HashSet<>();
21+
for (int i = 0; i < m; i++) {
22+
long a = scanner.nextInt() - 1;
23+
long b = scanner.nextInt() - 1;
24+
long key = a << 32 | b;
25+
set.add(key);
26+
for (int[] d : DIRECTIONS) {
27+
long nx = a + d[0];
28+
long ny = b + d[1];
29+
if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
30+
key = nx << 32 | ny;
31+
set.add(key);
32+
}
33+
}
34+
}
35+
long ans = n * n - set.size();
36+
return String.valueOf(ans);
37+
}
38+
}
39+
/*
40+
C - Avoid Knight Attack
41+
https://atcoder.jp/contests/abc377/tasks/abc377_c
42+
43+
题目大意:
44+
有一个由 $N^2$ 个正方形组成的网格,网格中有 $N$ 行和 $N$ 列。让 $(i,j)$ 表示从顶端 $(1\leq i\leq N)$ 起的第 $i$ 行和从左侧 $(1\leq j\leq N)$ 起的第 $j$ 列的正方形。
45+
每个方格要么是空的,要么放了一颗棋子。网格上有 $M$ 个棋子,而 $k$ -th $(1\leq k\leq M)$ 个棋子被放在了 $(a_k,b_k)$ 个方格上。
46+
您想把棋子放在**个空格**上,使它**不能被任何现有棋子吃掉**。
47+
放置在位置 $(i,j)$ 上的棋子可以吃掉满足以下任何条件的棋子:
48+
- 置于位置 $(i+2,j+1)$ 上
49+
- 置于位置 $(i+1,j+2)$ 上
50+
- 置于位置 $(i-1,j+2)$ 上
51+
- 置于位置 $(i-2,j+1)$ 上
52+
- 置于 $(i-2,j-1)$ 方格上
53+
- 置于 $(i-1,j-2)$ 方格上
54+
- 置于 $(i+1,j-2)$ 方格上
55+
- 置于 $(i+2,j-1)$ 方格上
56+
在这里,涉及不存在的正方形的条件被认为是永远不会满足的。
57+
例如,放在 $(4,4)$ 位置上的棋子可以吃掉放在下图中蓝色所示位置上的棋子:
58+
您可以将棋子放在几个位置上?
59+
#### 限制因素
60+
- $1\leq N\leq10^9$
61+
- $1\leq M\leq2\times10^5$
62+
- $1\leq a_k\leq N,1\leq b_k\leq N\ (1\leq k\leq M)$
63+
- $(a_k,b_k)\neq(a_l,b_l)\ (1\leq k\lt l\leq M)$
64+
- 所有输入值均为整数。
65+
66+
n 达到 1e9,不能暴力枚举,需要引入 哈希表 去重。
67+
======
68+
69+
Input 1
70+
8 6
71+
1 4
72+
2 1
73+
3 8
74+
4 5
75+
5 2
76+
8 3
77+
Output 1
78+
38
79+
80+
Input 2
81+
1000000000 1
82+
1 1
83+
Output 2
84+
999999999999999997
85+
86+
Input 3
87+
20 10
88+
1 4
89+
7 11
90+
7 15
91+
8 10
92+
11 6
93+
12 5
94+
13 1
95+
15 2
96+
20 10
97+
20 15
98+
Output 3
99+
338
100+
*/

0 commit comments

Comments
 (0)