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

AtCoder Beginner Contest 302

image

F 看错题了,以为是求取得 \(1,2,\dots,m\) 。 后面npy告诉我是 \(1 \text{ and } m\) 。

A - Attack

\(B \times x \geq A\) ,求 \(x\)

void solve()
{       
    ll a, b;    cin>>a>>b;
    cout<<(a / b) + (a % b != 0)<<'\n';
    return;
}

B - Find snuke

8 个方向找 \(\text{snuke}\)

int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
 
int n, m;
string op[110];
string s = "snuke";
void solve()
{       
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
    {
        cin>>op[i];
        op[i] = "?" + op[i];
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            for(int k = 0; k < 8; k++)
            {
                bool ok = false;
                int x = i + 4 * dx[k];
                int y = j + 4 * dy[k];
                if(x < 1 || x > n || y < 1 || y > m)
                    continue;
                for(int q = 0; q <= 4; q++)
                {
                    x = i + q * dx[k];
                    y = j + q * dy[k];
                    if(x < 1 || x > n || y < 1 || y > m)
                        break;
                    if(op[x][y] != s[q])
                        break;
 
                    if(q == 4)
                        ok = true;
                }
                if(ok)
                {
                    for(int q = 0; q <= 4; q++)
                        cout<<i + q * dx[k]<<" "<<j + q * dy[k]<<'\n';
                    return;
                }
 
            }
        }
    }
    return;
}

C - Almost Equal

全排列判断

int n, m;
 
string op[110];
int id[10];
bool vis[10], ok = false;
void dfs(int u)
{
    if(u == n)
    {
        for(int i = 2; i <= n; i++)
        {
            int cnt = 0;
            for(int j = 0; j < m; j++)
                if(op[id[i]][j] != op[id[i - 1]][j])
                    cnt++;
            if(cnt != 1)
                return;
        }
        ok = true;
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(!vis[i])
        {
            vis[i] = true;
            id[u + 1] = i;
            dfs(u + 1);
            vis[i] = false;
            id[u + 1] = 0;
        }
    }
}
 
void solve()
{       
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
        cin>>op[i];
    dfs(0);
    if(ok)
        cout<<"Yes\n";
    else
        cout<<"No\n";
    return;
}

D - Impartial Gift

对 B 序列排序后,分别找出 \(A_i (1 \leq i \leq N)\) 在 B 序列中分别找出 \(A_i-d \leq B_j\) 中最小的\(B_j\) 和 \(B_j \leq A_i + d\) 中最大的 \(B_j\) 。直接找会 TLE,但将 B 序列排序后,有序即可二分,时间复杂度 \(O(N \log M)\) 。

要注意二分得到的数只满足一个条件,最后要判断一下是否满足\(A_i - d \leq B_J \leq A_i + d\)

int n, m;
ll a[N], b[N], d;
void solve()
{       
    cin>>n>>m>>d;
    for(int i = 1; i <= n; i++)
        cin>>a[i];
    for(int j = 1; j <= m; j++)
        cin>>b[j];
    sort(a + 1, a + 1 + n);
    sort(b + 1, b + 1 + m);
    ll ans = -1;
    for(int i = 1; i <= n; i++)
    {
        int l = 1, r = m;
        while(l < r)
        {
            int mid = (l + r) >> 1;
            if(b[mid] >= a[i] - d) r = mid;
            else l = mid + 1;
        }  
        if(b[l] >= a[i] - d && b[l] <= a[i] + d)
            ans = max(ans, a[i] + b[l]);
        l = 1, r = m;
        while(l < r)
        {
            int mid = (l + r + 1) >> 1;
            if(b[mid] <= a[i] + d) l = mid;
            else r = mid - 1;
        }
        if(b[l] >= a[i] - d && b[l] <= a[i] + d)
            ans = max(ans, a[i] + b[l]);       
    }
    cout<<ans<<'\n';
    return;
}

E - Isolation

对于每个点,我们要统计如下:

  1. 操作1,u,v 连一条边,我们分别在 \(\text{set}_u, \text{set}_v\) 中记录边,分别查看其的度数,若为 \(0\) , \(\text{答案} - 1\) 并将 u, v 的度数加 \(1\)
  2. 将和 u 有两边的点的度数减 \(1\) , 若为 \(0\) , \(\text{答案} + 1\) , 并删去其边,将 u 的边集清空,度数赋值为 \(0\) , \(\text{答案} +1\) 。
int n, q, d[N];
set<int> e[N];
void solve()
{       
    cin>>n>>q;
    int res = n;
    for(int i = 1; i <= q; i++)
    {
        int opt; cin>>opt;
        if(opt == 1)
        {
            int u, v;   cin>>u>>v;
            if(d[u] == 0)
                res--;
            if(d[v] == 0)
                res--;
            d[u]++, d[v]++;
            e[u].insert(v);
            e[v].insert(u);
        }
        else
        {
            int u; cin>>u;
            vector<int> a;
            for(auto &it : e[u])
                a.push_back(it);
            for(auto &it : a)
            {
                e[it].erase(u);
                d[it]--;
                if(d[it] == 0)
                    res++;
            }
            e[u].clear();
            if(d[u] != 0)
                res++;
            d[u] = 0;
        }
        cout<<res<<'\n';
    }
    return;
}

F - Merge Set

问合并集合取得 \(1 \text{ and } m\) 的最小路径, 一眼 \(\text{BFS}\)

记录这个点可以到哪些集合,记录集合可以到哪些点

\(\text{BFS}\) 里面存的是点 \(u\),遍历 \(u\) 的集合中其他的点 \(v\), 然后是常规的 \(BFS\) 操作了。

int n, m, dist[N];
vector<int> e1[N], e2[N];
bool vis[N];
void bfs()
{
    for(int i = 1; i <= m; i++)
        dist[i] = 1e9;
    queue<int> q;
    q.push(1);
    dist[1] = 0;
    while(!q.empty())
    {
        auto u = q.front(); q.pop();
        for(auto &it : e1[u])
        {
            if(vis[it]) continue;
            vis[it] = true;
            for(auto &v : e2[it])
            {
                if(dist[v] > dist[u] + 1)
                {
                    dist[v] = dist[u] + 1;
                    if(v == m)
                    {
                        cout<<dist[u]<<'\n';
                        return;
                    }
                    q.push(v);
                }
            }
        }
    }
    cout<<-1<<'\n';
}
void solve()
{       
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
    {
        int len;    cin>>len;
        while(len--)
        {
            int x;  cin>>x;
            e1[x].push_back(i);
            e2[i].push_back(x);        
        }
    }
    bfs();

    return;
}

本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/17496565.html

posted on 2023-06-21 16:20  magicat  阅读(34)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3