首页 > 其他分享 >AtCoder Beginner Contest 287

AtCoder Beginner Contest 287

时间:2023-01-28 23:35:31浏览次数:72  
标签:tmp AtCoder cout Beginner int cin 字符串 using 287

A - Majority (abc287 a)

题目大意

给定\(n\)个人对某个提案的意见,问大多数意见是支持还是反对

解题思路

统计比较即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);
    int n;
    cin >> n;
    int ans = 0;
    while(n--){
        string s;
        cin >> s;
        ans += (s[0] == 'F') * 2 - 1;
    }
    if (ans > 0)
        cout << "Yes" << '\n';
    else
        cout << "No" << '\n';;

    return 0;
}



B - Postal Card (abc287 b)

题目大意

给定\(n\)个字符串和 \(m\)个模板。

问有多少个字符串的后缀包含在这 \(m\)个模板内。

解题思路

set储存这些模板,然后对于每个字符串直接查找即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector<string> s(n);
    for(auto &i : s)
        cin >> i;
    set<string> f;
    for(int i = 0; i < m; ++ i){
        string s;
        cin >> s;
        f.insert(s);
    }
    int ans = count_if(s.begin(), s.end(), [&](string& a){
            return f.count(a.substr(3)) > 0;
            });
    cout << ans << '\n';

    return 0;
}



C - Path Graph? (abc287 c)

题目大意

给定一张图,问是不是一个链。

解题思路

链的性质就是:

  • 一个连通块
  • 两个点度数为\(1\),其余点度数为 \(2\)。
神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> du(n, 0);
    vector<int> fa(n, 0);
    iota(fa.begin(), fa.end(), 0);
    function<int(int)> findfa = [&](int x){
        return fa[x] == x ? x : fa[x] = findfa(fa[x]);
    };
    for(int i = 0; i < m; ++ i){
        int u, v;
        cin >> u >> v;
        -- u;
        -- v;
        du[u] ++;
        du[v] ++;
        int fu = findfa(u);
        int fv = findfa(v);
        if (fu != fv)
            fa[fu] = fv;
    }
    int one = count(du.begin(), du.end(), 1);
    int two = count(du.begin(), du.end(), 2);
    int block = 0;
    for(int i = 0; i < n; ++ i)
        block += (fa[i] == i);
    if (one == 2 && two == n - 2 && block == 1)
        cout << "Yes" << '\n';
    else 
        cout << "No" << '\n';

    return 0;
}



D - Match or Not (abc287 d)

题目大意

给定两个由小写字母和?组成的字符串\(S,T\),

对于 \(x \in [0,|T|]\) ,问\(S^\prime\)和 \(T\)是否匹配

其中 \(S^\prime\)由 \(S\)串的前 \(x\)个字符和后 \(|T| - x\)个字符组成。

两个字符串匹配,当且仅当将其中的 ?替换成英文字母后,两个字符串相同。

解题思路

两个字符串匹配,当且仅当每一位要么是相同字母,要么至少有一个?。于是我们可以储存所有不满足这些条件的位数。当且仅当该位数为\(0\)时,两个字符串匹配。

注意到当\(x\)递增的时候,前后两个 \(S^\prime\)仅有一个位置不同,因此我们可以继承上一个状态,仅修改变化的位置能否匹配即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);
    string s, t;
    cin >> s >> t;
    int n = s.size();
    int m = t.size();
    unordered_set<int> bad;
    int tp = 0;
    for(int i = n - m; i < n; ++ i, ++ tp){
        if (s[i] != '?' && t[tp] != '?' && s[i] != t[tp])
            bad.insert(tp);
    }
    if (bad.empty())
        cout << "Yes" << '\n';
    else 
        cout << "No" << '\n';
    for(int i = 0; i < m; ++ i){
        bad.erase(i);
        if (s[i] != '?' && t[i] != '?' && s[i] != t[i])
            bad.insert(tp);
        if (bad.empty())
            cout << "Yes" << '\n';
        else 
            cout << "No" << '\n';
    }

    return 0;
}



E - Karuta (abc287 e)

题目大意

给定\(n\)个字符串,对于每个字符串 \(s_i\),问 \(\max LCP(s_i, s_j)_{i \neq j}\),其中\(LCP\)是最长公共前缀。

解题思路

注意到最大的最长公共前缀一定在字典序上前后两个的字符串之间,因此将这\(n\)个字符串按字典序排序,求每个字符串与其相邻的字符串的\(LCP\),取最大值即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);
    int n;
    cin >> n;
    vector<string> s(n);
    for(auto &i : s)
        cin >> i;
    vector<int> id(n);
    iota(id.begin(), id.end(), 0);
    sort(id.begin(), id.end(), [&](int x, int y){
            return s[x] < s[y];
    });
    vector<int> ans(n);
    auto LCP = [&](string& l, string& r){
        int tmp = 0;
        while(tmp < l.size() && tmp < r.size() && l[tmp] == r[tmp])
            ++ tmp;
        return tmp;
    };
    for(int i = 0; i < n - 1; ++ i){
        int l = id[i], r = id[i + 1];
        int tmp = LCP(s[l], s[r]);
        ans[l] = max(ans[l], tmp);
        ans[r] = max(ans[r], tmp);
    }
    for(auto &i : ans)
        cout << i << '\n';

    return 0;
}



F - Components (abc287 f)

题目大意

给定一棵有\(n\)个点的树,在所有\(2^n - 1\)的非空点集中,回答下列问题:

对于\(i \in [1,n]\) ,有多少个点集所形成的连通块个数恰好是\(i\)。

数量对 \(998244353\)取模。

解题思路

当设\(dp[u][i]\)表示以 \(u\)为根的子树,能形成连通块数量恰好为 \(i\)的,点集数时,会发现在合并子树的时候,如果点\(u\)和子树节点都选择的时候,连通块个数会减一,其余情况都不会,因此还要加上是否选择点 \(u\)的状态。

设\(dp[u][i][0/1]\)表示以 \(u\)为根的子树,能形成连通块数量恰好为 \(i\)的,且不选择/选择点 \(u\)的点集数。

转移时枚举儿子树的连通块大小。

咋一看这样的复杂度会是\(O(n^3)\),但如果每次枚举的范围都是儿子树的大小,可以证明这样的树型 \(dp\)的复杂度是 \(O(n^2)\)的。

神奇的代码



G - Balance Update Query (abc287 g)

题目大意

有\(N\)种类型的卡,每种卡有\(10^{100}\)张。每种卡有分数大小属性。

维护以下三种操作:

  • 1 x y,将第\(x\)种卡的分数修改为\(y\)。
  • 2 x y,将第\(x\)种卡的大小修改为\(y\)。
  • 3 x,选\(x\)张卡,要求最大化分数和,且每种类型的卡的数量不得超过其大小

解题思路

不考虑修改,仅考虑询问的话,很显然我们从分数大的卡贪心取,直到取了\(x\)张。由于张数随着种类的增加而越来越多,因此可以二分取的卡的种类,计算一下取的卡的数量(其实就是大小属性的前缀和)求得答案。

而如果加上操作 \(2\),实际上是要维护下大小属性的前缀和,用线段树维护即可(线段树二分的话复杂度还是不变的)

但如果加上操作\(1\)的话,就要动态维护卡的顺序就寄了,后续再思索思索。

神奇的代码



Ex - Directed Graph and Query (abc287 h)

题目大意

给定一张有向图,回答\(q\)组询问。

每组询问包括 \(s,t\),问从 \(s\)到点 \(t\)的路径的代价最小值。

一条路径的代价是其经过的点的编号的最大值。

解题思路

如果是无向图,可以对原图跑一棵最小生成树,边权就是两点的点编号较大的那个。

然后每次询问其最大的,连接了这两个点的点,就是Kruscal重构树中两点的LCA

但这是有向图。再思索思索。

神奇的代码



标签:tmp,AtCoder,cout,Beginner,int,cin,字符串,using,287
From: https://www.cnblogs.com/Lanly/p/17071525.html

相关文章

  • AtCoder Beginner Contest 287
    纯纯手速场C首先这张图必须是一棵树,必有\(M=N-1\)。接下来只需求出树的直径,判断其长度(边数)是否为\(N-1\)即可。https://atcoder.jp/contests/abc287/submissions/3......
  • Atcoder Beginner Contest 287
    赛时吃了三个法师,不过问题不大。赛时AB简单字符串处理。C中需要满足:\(m=n-1\)只有两个度数为\(1\)的点,剩下点的度数都为\(2\)。记得判连通!!D根据题目要求观......
  • AtCoder Beginner Contest 130
    AtCoderBeginnerContest130https://atcoder.jp/contests/abc130补补之前的A-Rounding#include<bits/stdc++.h>usingnamespacestd;intmain(){inta......
  • Atcoder ABC244E - King Bombee 题解
    原题:AtcoderABC244E-KingBombee题意给你一张图,从\(S\)到\(T\),经过\(k\)条边,经过\(X\)号点偶数次的方案数。做法设\(f_{i,j,k}\)表示经过\(i\)条边,......
  • AtCoder Beginner Contest 159
    A-TheNumberofEvenPairs相加为偶数只有偶加偶和奇加奇两种情况,其实就是在\(n\)个数中取两个(\(C\binom{2}{n}\)),在\(m\)个数中取两个(\(C\binom{2}{m}\))。B-String......
  • AtCoder Beginner Contest 126
    AtCoderBeginnerContest126https://atcoder.jp/contests/abc126A-ChangingaCharacter#include<bits/stdc++.h>usingnamespacestd;intmain(){int......
  • AtCoder Beginner Contest 162
    A-Lucky7大水题,模拟即可。#include<iostream>#include<cstdio>usingnamespacestd;intmain(){strings;cin>>s;if(s[0]=='7'||s[1]==......
  • AtCoder Beginner Contest 172
    A-Calc(abc172a)题目大意给定一个\(a\),输出\(a+a^2+a^3\)解题思路模拟即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=long......
  • 【最短路】Atcoder Beginner Contest 286----E
    题目:E-Souvenir(atcoder.jp)题解:首先这道题可以很容易看出来是求最短路。最开始自己是用bfs写的,出现了WA,TLE,RE等错误。因为对于每种情况会有Q次询问,如果每次询问都......
  • 【多重背包】Atcoder Beginner Contest 286----D
    题目:D-MoneyinHand(atcoder.jp)分析:经典的多重背包。用dp[i]表示i能否正好凑出。先复习一下多重背包。多重背包就是有N组物品,每组最多有k个,每组可以选多个。分组背......