AtCoder Beginner Contest 196(DE)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 196(DE)相关的知识,希望对你有一定的参考价值。
链接: link.
D - Hanjo
题意:
给定一个 N × M N×M N×M的矩阵,现在有 A A A个 1 × 2 1×2 1×2的小方块(可以横着用,也可以竖着用), B B B个 1 × 1 1×1 1×1的小方块,现在问用这些方块填满矩阵,有多少种放法?
思路
直接状态压缩+dfs,把整个矩阵看成一维的
[
0
,
n
×
m
−
1
]
[0,n×m-1]
[0,n×m−1]放
1
×
1
1×1
1×1一直横着放就行,当要放
1
×
2
1×2
1×2的小方块时,考虑竖着放和横着放的两种形式,当放完时答案
+
1
+1
+1,用二进制
b
i
t
bit
bit记录那些位置被占据了,当当前位置已经枚举过的时候,就需要换到下一个位置,位置变换时,不用考虑该向哪个方向拓展了,由于已经展成一维的了,一个一个放即可。
也可以用二维坐标来存,不用状态压缩
#include <bits/stdc++.h>
using namespace std;
int n, m, a, b;
int res;
void dfs(int pos, int state, int a, int b)
if (pos == n * m)
res++;
return;
if (state & (1 << pos))
dfs(pos + 1, state, a, b);
if (a)
if (pos % m != m - 1 && !(state & (1 << (pos + 1))))
dfs(pos + 1, state | (1 << (pos + 1)) | (1 << pos), a - 1, b);
if (!(state & (1 << (pos + m))))
dfs(pos + 1, state | (1 << (pos + m)) | 1 << pos, a - 1, b);
if (b)
dfs(pos + 1, state | (1 << pos), a, b - 1);
int main()
cin >> n >> m >> a >> b;
dfs(0, 0, a, b);
cout << res << endl;
E - Filters
题意:
给定一个函数形式,现在给定
N
N
N个二元组
(
t
i
,
a
i
)
(t_i,a_i)
(ti,ai)
下面有
Q
Q
Q次询问,查询
f
N
(
.
.
.
.
.
.
f
2
(
f
1
(
x
)
)
)
f_N(......f_2(f_1(x)))
fN(......f2(f1(x)))
经过画图,根据
a
i
a_i
ai的不同,如果三种
t
i
t_i
ti都存在的话,图形就会类似于,即
F
(
x
)
=
m
i
n
(
c
,
m
a
x
(
b
,
x
+
a
)
)
F(x)=min(c,max(b,x+a))
F(x)=min(c,max(b,x+a))
假设
f
(
x
)
=
m
i
n
(
c
1
,
m
a
x
(
b
1
,
x
+
a
1
)
)
f(x)=min(c_1,max(b_1,x+a_1))
f(x)=min(c1,max(b1,x+a1))
g
(
x
)
=
m
i
n
(
c
2
,
m
a
x
(
b
2
,
x
+
a
2
)
)
g(x)=min(c_2,max(b_2,x+a_2))
g(x)=min(c2,max(b2,x+a2))
那么
g
(
f
(
x
)
)
=
m
i
n
(
m
i
n
(
c
2
,
m
a
x
(
b
2
,
c
1
+
a
2
)
)
,
m
a
x
(
m
a
x
(
b
2
,
m
i
n
(
c
1
+
a
2
,
b
1
+
a
2
)
)
,
x
+
(
a
1
+
a
2
)
)
)
g(f(x))=min(min(c_2,max(b_2,c1+a2)),max(max(b_2,min(c_1+a_2,b_1+a_2)),x+(a_1+a_2)))
g(f(x))=min(min(c2,max(b2,c1+a2)),max(max(b2,min(c1+a2,b1+a2)),x+(a1+a2)))
推导直接看官方的 link.
所以,每次对于
t
1
t_1
t1就相当于把函数整体上下平移,记录偏移量即可
t
2
t_2
t2 斜线左端点沿着斜线向右上方平移,相当于把下面小的部分折成平的,
m
i
n
min
min向上平移
t
3
t_3
t3斜线右端点沿着斜线向左下方平移,相当于把上面大的部分折成平的,
m
a
x
max
max向下平移
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 1e17;
int maxx = inf, minn = -inf;
int add = 0;
int n;
signed main()
cin >> n;
for (int i = 1; i <= n; i++)
int x, t;
cin >> x >> t;
if (t == 1)
add += x;
maxx += x;
minn += x;
if (t == 2)
minn = max(minn, x);
maxx = max(maxx, x);
if (t == 3)
minn = min(minn, x);
maxx = min(maxx, x);
int T;
cin >> T;
while (T--)
int x;
cin >> x;
if (x + add <= minn)
cout << minn << endl;
else if (x + add >= maxx)
cout << maxx << endl;
else
cout << x + add << endl;
F F F涉及多项式乘法,不太会,没补
以上是关于AtCoder Beginner Contest 196(DE)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解