• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
nannandbk
博客园    首页    新随笔    联系   管理    订阅  订阅
AtCoder Beginner Contest 334 ABCDE

AtCoder Beginner Contest 334](https://atcoder.jp/contests/abc334) ABCDE

A - Christmas Present

签到不多说。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int a,b; cin>>a>>b;
    cout<<(a>b?"Bat":"Glove")<<"\n";


    return 0;
}

B - Christmas Trees

题意:给你 \(A,M,L,R\) ,表示在一个坐标轴上,对于任意的整数 \(k\) ,在 \(A+kM\) 的位置都种上了圣诞树,现问你 \([L,R]\) 的区间内有多少圣诞树?

思路:分类讨论,考虑\(A\)和区间\([L,R]\)的关系。

  1. 如果\(A\)在\([L,R]\)之间(\(L \le A \le R\))。

    \(res = (A-L)/M + (R-A)/M +1\) (+1是因为k可以等于0)

  2. \(A\)在区间\([L,R]\)左边(\(A<L\))。

    前缀和思想,\(pre[R]-pre[L-1]\)

    \(res = (R-A)/M - ((L-1)-A)/M\)

  3. \(A\)在区间\([L,R]\)右边边(\(A>R\))。

    \(pre[L]-pre[R+1]\)

​ \(res = (A-L)/M - (A-(R+1))/M\)

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    ll a,m,l,r; cin>>a>>m>>l>>r;

    ll res = 0;
    if(a < l)
    {
        res = (r-a)/m - ((l-1)-a)/m;
    }
    else if(l <= a && a <= r)
    {
        res = (r-a)/m + (a-l)/m + 1;
    }
    else if(a > r)
    {
        res = (a-l)/m - (a-(r+1))/m;
    }
    cout<<res<<"\n";

    return 0;
}

C - Socks 2

题意:高桥君有 \(N\) 双袜子,第 \(i\) 双袜子的编号是 \(i\) ,有一天他突然意识到了自己丢失了 \(K\) 只袜子,我们定义两只袜子的 “差异度” 为这两只袜子编号的差的绝对值。

现给你这 \(K\) 只袜子的编号,把剩余的 \(2N-K\) 只袜子两两配对,求配对后差异度和的最小值。注意到如果 \(K\) 是奇数,配对后剩余一只袜子是允许的,且不算入差异度的计算中。

第一行输入 \(N,K\),第二行输入 \(K\) 个数表示丢失的袜子的编号。

思路:思考怎么样差异度最小,肯定是排序之后相邻两个配对是最优的。

那么如果是偶数个之间两两配对即可。如果是奇数个呢?有一个是多出来的,那么是哪一个呢?不知道,我们考虑对前后缀都做一次前缀/后缀和,枚举是哪一个不要,答案取min就行了。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 5e5 + 10;
int a[N],cnt;
ll pre[N],suf[N],res;
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int n,k; cin>>n>>k;
    set<int>s;
    vector<int>v;
    for(int i = 1;i <= k; i++)
    {
        int x; cin>>x;
        s.insert(x);
    }
    for(int i = 1;i <= n; i++)
    {
        a[++cnt] = i;
        if(s.find(i) == s.end())
            a[++cnt] = i;
    }
    int m = 2*n-k;
    // for(int i = 1;i <= m; i++)
    //     cout<<a[i]<<" ";
    // cout<<"\n";
    for(int i = 1;i <= m; i += 2)
    {
        pre[i] = pre[i-1] + abs(a[i]-a[i+1]);
        pre[i+1] = pre[i];                         
    }

    for(int i = m;i >= 1; i -= 2)
    {
        suf[i] = suf[i+1] + abs(a[i]-a[i-1]);
        suf[i-1] = suf[i];
    }

    if(m % 2 == 0){
        res = pre[m];
    }else{
        res = 1e9;
        for(int i = 1;i <= m; i++)
        {
            res = min(res,pre[i-1]+suf[i+1]);
        }
    }
    cout<<res<<"\n";
    return 0;
}

D - Reindeer and Sleigh

题意:有 \(N\) 个雪橇,其中第 \(i\) 个雪橇需要 \(R_i\) 匹驯鹿来拉。每匹驯鹿最多拉一个雪橇。现有 \(Q\) 次询问,每次询问给你 \(X\) ,问你如果有 \(X\) 匹驯鹿,最多能拉多少个雪橇?

第一行输入 \(N,Q\),第二行输入 \(R_i\),接下来每行输入一个询问。

思路:排序+二分。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
ll need[N],s[N];

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int n,q; cin>>n>>q;

    for(int i = 1;i <= n; i++)
        cin>>need[i];
    sort(need+1,need+1+n);
    for(int i = 1;i <= n; i++)
        s[i] = s[i-1]+need[i];
 
    for(int tc = 1;tc <= q; tc++)
    {
        ll x;  cin>>x;
        ll l = 0, r = n;
        while(l<=r)
        {
            ll mid = (l+r)>>1;
            if(s[mid] <= x)l = mid+1;
            else r = mid-1;
        }
        cout<<l-1<<"\n";
    }

    return 0;
}

E - Christmas Color Grid 1

题意:给定 \(n\times m\) 的字符矩阵,# 表示绿色,. 表示红色。

均匀随机一个红色块换成绿色,求绿色四连通块的期望数量,对 \(998244353\) 取模。

\(1\le n,m\le 1000\)

题意:先用\(dfs\)分块,每个连通块标号。然后我们for一边,遇到每一个\(.\)去看它的四个方向有几种连通块,如果有的话就加上\(max(0,原来的连通块数-这个\).\(四个方向上的连通块种类数+1)\)。取max是因为可能这个点四周没有连通块,防止是负数。那么如果四周没有连通块的话答案加上\(原连通块数+1\)。最后的话用除法逆元求答案即可。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int mod = 998244353;
const int N = 2e5 + 10;
ll n,m,hav;
int cnt = 1;
char a[1010][1010];
int b[1010][1010];
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
bool in(int x,int y)
{
    return x >= 1 && x <= n && y >= 1 && y <= m;
}
void dfs(int x,int y,int num)
{
    b[x][y] = num;
    for(int i = 0;i < 4; i++)
    {
        int tx = x + dir[i][0];
        int ty = y + dir[i][1];
        if(in(tx,ty) && a[tx][ty]=='#' && !b[tx][ty])
        {
            dfs(tx,ty,num);
        }
    }
}
ll qmi(ll a, ll b, ll mod)
{
    ll ans = 1 % mod;
    while(b)
    {
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

signed main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    cin>>n>>m;
    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= m; j++)
            cin>>a[i][j];

    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= m; j++)if(a[i][j]=='#' && !b[i][j]){
            dfs(i,j,cnt);
            cnt++,hav++;
        }

    // for(int i = 1;i <= n; i++)
    // {
    //     for(int j = 1;j <= m; j++)
    //     {
    //         cout<<a[i][j];
    //     }
    //     cout<<"\n";
    // }
    ll cnt = 0,ans = 0;
    for(int i = 1;i <= n; i++)
    {
        for(int j = 1;j <= m; j++)
        {
            if(a[i][j]=='.')
            {
                cnt++;
                set<ll>s;
                int d = 0;
                for(int k = 0;k < 4; k++)
                {
                    int tx = i + dir[k][0];
                    int ty = j + dir[k][1];
                    if(in(tx,ty)&&a[tx][ty] != '.')s.insert(b[tx][ty]);
                    if(in(tx,ty) && a[tx][ty]=='.')d++;
                }
                if(s.size() == 0 && d)ans++;
               // cout<<"s.size() = "<<s.size()<<"\n";
                // for(auto x : s)
                //     cout<<x<<" ";
                // cout<<"\n";
                // cout<<"!!"<<hav-(s.size()-1)<<"\n";
                ans += hav-max(0ll,(ll)s.size()-1);

            }
        }
    }
    ll g = __gcd(ans,cnt);
     // cout<<"hav = "<<hav<<"\n";
     // cout<<"ans = "<<ans<<" cnt = "<<cnt<<"\n";
    if(g)
        ans /= g,cnt /= g;
    int inv = qmi(cnt, mod - 2, mod)%mod;
    cout<<ans%mod*inv%mod<<"\n";
    return 0;
}

posted on 2024-02-03 23:59  nannandbk  阅读(56)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3