Atcoder Beginner Contest 311 A~D题解

文章目录

  • A - First ABC
  • B - Vacation Together
  • C - Find it!
  • D - Grid Ice Floor

隔了一个多月回来摸摸鱼,E题开摆

A - First ABC

出现首次出现ABC三种字符的子串长度

#include 
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i++)
#define df(i, j, k) for (int i = j; i >= k; i--)

using namespace std;

void solve()
{
    int n;
    string s;
    cin >> n >> s;
    bool st[3]{};
    int flag = 0, count = 0;
    for (auto ch : s)
    {
        count++;
        if (st[ch - 'A']) continue;
        else
        {
            st[ch - 'A'] = 1;
            flag++;
        }
        if (flag == 3) break;
    }
    cout << count << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--) solve();
    return 0;
}

B - Vacation Together

找出最长n个人都有空的连续序列

#include 
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i++)
#define df(i, j, k) for (int i = j; i >= k; i--)

using namespace std;

void solve()
{
    int n, m;
    cin >> n >> m;
    vector<string> s(n);
    uf(i, 0, n - 1) cin >> s[i];
    int ans = 0;
    int cnt = 0;
    uf(i, 0, m - 1)
    {
        bool st = true;
        uf(j, 0, n - 1)
        {
            if (s[j][i] == 'o') continue;
            st = 0;
            break;
        }
        if (st) cnt ++;
        else cnt = 0;
        ans = max(ans, cnt);
    }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}

C - Find it!

找出有向图中的一个环,环中结点不重复

  • 先拓扑排序,后递归找环
#include 
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i++)
#define df(i, j, k) for (int i = j; i >= k; i--)

using namespace std;

const int N = 2e5 + 5;
vector<vector<int>> e(N, vi());
vector<int> in(N, 0);
bool st[N];
vector<int> ans;

bool dfs(int u, int p)
{
    if (u == p)
    {
        ans.push_back(p);
        return true;
    }
    for (auto v : e[u])
    {
        if (st[u])
            continue;
        st[u] = 1;
        ans.push_back(u);
        if (dfs(v, p))
            return true;
        ans.pop_back();
        st[u] = 0;
    }
    return false;
}

void solve()
{
    int n;
    cin >> n;
    uf(i, 1, n)
    {
        int t;
        cin >> t;
        e[i].push_back(t);
        in[t]++;
    }
    queue<int> q;
    uf(i, 1, n)
    {
        if (in[i] == 0)
            q.push(i);
    }
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        if (st[t])
            continue;
        st[t] = 1;
        for (auto v : e[t])
        {
            in[v]--;
            if (in[v] == 0)
            {
                q.push(v);
            }
        }
    }
    uf(i, 1, n)
    {
        if (!st[i])
        {
            for (auto v : e[i])
            {
                if (dfs(v, i))
                {
                    cout << ans.size() << endl;
                    for (auto x : ans)
                        cout << x << " ";
                    return;
                }
            }
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}

D - Grid Ice Floor

只能从上下左右方向一滑到底,求能够滑到的最大格子数

  • bfs 每个方向都判断一次,只要接下来存在没有走过的格子,就能在这个方向上一滑到底
#include 
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i ++)
#define df(i, j, k) for (int i = j; i >= k; i --)

using namespace std;

const int N = 210;
char mp[N][N];
int d[] {0, -1, 0, 1, 0};
int n, m;
bool st[N][N];
int ans=  0;

// 检查约束
constexpr bool checkConstraint(int x, int y)
{
    return x > 1 && x < n && y > 1 && y < m && mp[x][y] == '.';
}
// 检查当前方向p是否存在没有走过的格子,即 cnt!=0, 同时返回滑到底的坐标
vector<int> check(int x, int y, int p)
{
    st[x][y] = 1;
    int dx = x + d[p], dy = y + d[p + 1], cnt = 0;
    while (checkConstraint(dx, dy) && (st[dx][dy] || ++ cnt) && (st[dx][dy] = true))
    {
        x = dx, y = dy;
        dx = x + d[p], dy = y + d[p + 1];
    }
    return {cnt, x, y};
}

void bfs()
{
    queue<pii> q;
    q.push({2, 2});
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        int x = t.x, y = t.y;
        for (int i = 0; i < 4; i ++)
        {
            auto res = check(x, y, i);
            if (!res[0]) continue; // 当前方向不存在没有走过的格子
            q.push({res[1], res[2]});
        }
    }
}



void solve()
{
    cin >> n >> m;
    uf (i, 1, n) cin >> mp[i] + 1;
    bfs();
    for (int i = 1; i <= n; i ++)
    {
        for (int j = 1; j <= m; j ++) 
        {
            if (st[i][j]) ans ++;
        }
    }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

输剩小小都算喺赢

你可能感兴趣的:(算法,c++)