【Atcoder】AGC021 B-F简要题解

本文详细介绍了Atcoder AGC021竞赛中的B至F题,包括B.Holes的凸包概率计算,C.Tiling的特殊情况处理,D.Reversed LCS的动态规划解法,E.Ball Eat Chameleons的分类讨论和路径计数,以及F.Trinity的矩阵染色问题。每道题目均提供了思路和部分代码实现。
摘要由CSDN通过智能技术生成

一场9h才做完的AGC,
我太菜了,哇的一声哭出来 (。﹏。)


*B.Holes

若所有点贡献则两个端点概率各为 0.5 0.5 0.5,其余点概率为 0 0 0

注意到 R = 1 0 1 0 1 0 10 R=10^{10^{10^{10}}} R=10101010实在太大了——求所有点的凸包,可以只计算凸包外的点到每个点的概率(凸包内的点可以忽略不计)。
凸包上每个点的概率即 π − θ i 2 π ( θ i \dfrac{\pi-\theta_i}{2\pi}(\theta_i 2ππθi(θi是点 i i i内夹角)

还有一种 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn)的很好写的算法,戳这里


*C.Tiling

划分成 4 × 4 4\times 4 4×4的小方格,若 n , m n,m n,m为奇,单独用 1 × 2 , 2 × 1 1\times 2,2\times 1 1×2,2×1去填补最后一行/列。
注意特判右下角 3 × 3 3\times 3 3×3的方格(3同3异换成2同2异):
<>^
^*v
v<>

code from yfzcsc

#include<bits/stdc++.h>
using namespace std;
char s[1010][1010];
int n,m,a,b;
int main(){
   
    scanf("%d%d%d%d",&n,&m,&a,&b);
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)s[i][j]='.';
    if(n&1)for(int i=1;i<m&&a;i+=2)s[n][i]='<',s[n][i+1]='>',a--;
    if(m&1)for(int i=1;i<n&&b;i+=2)s[i][m]='^',s[i+1][m]='v',b--;
    for(int i=1;i<n;i+=2)
        for(int j=1;j<m;j+=2){
   
            if(a>=2){
   
                a-=2;
                s[i][j]='<',s[i][j+1]='>';
                s[i+1][j]='<',s[i+1][j+1]='>';
            } else if(b>=2){
   
                b-=2;
                s[i][j]='^',s[i][j+1]='^';
                s[i+1][j]='v',s[i+1][j+1]='v';
            } else if(a&&b&&i==n-2&&j==m-2){
   
                a--,b--;
                s[i][j]='<',s[i][j+1]='>',s[i][j+2]='^';
                s[i+1][j]='^',s[i+1][j+2]='v';
                s[i+2][j]='v',s[i+2][j+1]='<',s[i+2][j+2]='>';
            } else if(a){
   
                a--;
                s[i][j]='<',s[i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值