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×m1] 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 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242