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

AtCoder Beginner Contest 311

时间:2023-07-25 13:22:40浏览次数:36  
标签:AtCoder Beginner int 311 nullptr cin long ++ vector

A - First ABC

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    string s;
    cin >> n >> s;
    set<char> cnt;
    int t = 0;
    for( auto i : s){
        t ++;
        cnt.insert(i);
        if( cnt.size() == 3 ) break;
    }
    cout << t << "\n";
    return 0;
}

B - Vacation Together

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n , d;
    cin >> n >> d;
    vector<int> vis(d);
    for( string s ; n ; n -- ){
        cin >> s;
        for( int i = 0 ; i < d ; i ++ )
            if( s[i] == 'x' ) vis[i] = 1;
    }
    int res = 0;
    for( int i = 0 , cnt = 0 ; i < d ; i ++ ){
        if( vis[i] ) cnt = 0;
        else cnt ++;
        res = max( res , cnt );
    }
    cout << res << "\n";
    return 0;
}

C - Find it!

#include <bits/stdc++.h>

using namespace std;

#define int long long

vector<int> vis , t , res;

void dfs( int x ){
    if( vis[x] == 1 ){
        res.push_back(x);
        vis[x] ++;
        dfs( t[x] );
    }else if( vis[x] == 2 ){
        return ;
    }else{
        vis[x] ++ ;
        dfs(t[x]);
    }

}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vis = vector<int>(n+1);
    t = vector<int>(n+1);
    for( int i = 1 ; i <= n ; i ++ )
        cin >> t[i];
    for( int i = 1 ; i <= n ; i ++ ){
        if( vis[i] ) continue;
        dfs(i);
        if( res.empty() ) continue;
        cout << res.size() << "\n";
        for( auto i : res )
            cout << i << " ";
        cout << "\n";
        return 0;
    }
    return 0;
}

D - Grid Ice Floor

暴力的 bfs,在 bfs 的过程中既记录当前的位置,同时记录移动方向

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

#define mp make_pair
#define mt make_tuple

int32_t main() {
//    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    vector<vector<int>> vis(n, vector<int>(m));
    for (auto &i: g) cin >> i;
    queue<tuple<int, int, int>> q;
    for (int i = 0; i < 4; i++)
        q.emplace(1, 1, i);
    while (!q.empty()) {
        auto [x, y, d] = q.front();
        q.pop();
        if (vis[x][y] & (1 << d)) continue;
        vis[x][y] |= (1 << d);
        int fx = x + dx[d], fy = y + dy[d];
        if (fx >= 0 && fx < n && fy >= 0 && fy < m && g[fx][fy] == '.')
            q.emplace(fx, fy, d);
        else if (fx >= 0 && fx < n  && fy >= 0 && fy < m && g[fx][fy] == '#') {
            for (int i = 0; i < 4; i++)
                if (i != d) q.emplace(x, y, i);
        }
    }
    int res = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            res += (vis[i][j] > 0) && (g[i][j] == '.');
        }
    }
    cout << res << "\n";
    return 0;
}

E - Defect-free Squares

二维前缀和,枚举点,然后二分最大边长即可

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve() {
    int n, m;
    cin >> n >> m;

}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n , m , q;
    cin >> n >> m >> q;
    vector<vector<int>> a( n+1 , vector<int>(m+1) );
    for( int  x , y ; q ; q -- )
        cin >> x >> y , a[x][y] = 1;
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = 1 ; j <= m ; j ++ )
            a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1];
    int res = 0;
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = 1 ; j <= m ; j ++ ){
            int l = 1 , r = 3000 , mid , ans = -1;
            while( l <= r ){
                mid = ( l + r ) >> 1;
                int x = i + mid - 1, y = j + mid-1 , cnt = 0;
                if( x > n || y > m ) cnt = 1;
                else cnt = a[x][y] - a[x][j-1] - a[i-1][y] + a[i-1][j-1];
                if( cnt == 0 ) ans = mid , l = mid + 1;
                else r = mid-1;
            }
            if( ans == -1 ) continue;
            res += ans;
        }
    cout << res << "\n";
    return 0;
}

F - Yet Another Grid Task

首先某一列的黑色一定是只能放最下面连续的一段。

根据题目的要求可知如果第\(i\)列放了\(x\)个,则\(i+1\)至少放\(x-1\)个。

首先求出每一列至少放\(a[i]\)个

\(f[i][j]\)表示第\(i\)列到第\(m\)列,且第\(i\)列放了\(j\)个黑色的方案数,则

\[f[i][j] = \sum_{k= j+1}^{n} f[i+1][k] \]

求和的过程可以用前缀和优化一下,从右往左 dp 一下就好了。

#include <bits/stdc++.h>

using namespace std;

#define int long long
const int mod = 998244353;

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    vector<int> a(m);

    for (int i = 0; i < n; i++) cin >> g[i];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            if (g[i][j] == '#') {
                a[j]++;
                if (i + 1 < n) g[i + 1][j] = '#';
                if (i + 1 < n && j + 1 < m) g[i + 1][j + 1] = '#';
            }
        }

    vector<int> s(n+2); // s[j] 存储是 f[i+1][j] 的前缀和
    s[n+1] = 1; // 因为 j 的取值是 [0,n] , 为了便于差分的计算映射到 [1,n+1] 上
    vector<vector<int>> f(m, vector<int>(n + 1)); // f[i][j] 第 i 列放 j 个黑色的方案数
    for (int i = m - 1; i >= 0; i--) {
        for (int j = a[i]; j <= n; j++)
            f[i][j] = ( s[n+1] - s[max(j-1,0ll)] + mod) % mod;
        s[1] = f[i][0];
        for (int j = 1; j <= n; j++)
            s[j+1] = (s[j] + f[i][j]) % mod;
    }
    cout << s[n+1] << "\n";
    return 0;
}

G - One More Grid Task

比较朴素的做法是枚举两个点确定矩形,然后通过各种预处理实现\(O(1)\)的求和和求最值,这样复杂度是\(O(N^4)\)

这里我们枚举两行,表示选取中间的部分,这样在通过\(O(n)\)的预处理可以把二维的压缩为一维,然后如果考虑枚举区间又是不行的,我们转变思路,枚举点计算每个点的最大贡献。

首先这个点如果要产生贡献,必须是区间内的最小值,这样我们找到\(l_i,r_i\)分别表示\(i\)左右两侧第一个\(i\)小的值的下标,这样我们区间取\([l_i+1,r_i-1]\)就是该点的最大贡献,求和的过程可以用前缀和来解决。

现在我们只剩下求\(l_i,r_i\),在序列上求两次第一个比他小的值是很经典的单调栈,可以\(O(n)\)的求出。

所以整体的复杂度就是\(O(N^3)\)

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int N, M;
    cin >> N >> M;
    vector a(N + 1, vector<int>(M + 1));
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= M; j++)
            cin >> a[i][j];

    int res = 0;
    for (int u = 1; u <= N; u++) {
        vector<int> s(M + 1, 0ll), m(M + 1, LLONG_MAX);
        for (int v = u; v <= N; v++) {
            for (int i = 1; i <= M; i++)
                s[i] += a[v][i], m[i] = min(m[i], a[v][i]);
            vector<int> l(M + 1, 0), r(M + 1, M + 1), stk;
            // l[i] , r[i] 表示左右两侧第一个比 i 小的数的下标
            for (int i = 1; i <= M; i++) {
                while (!stk.empty() && m[i] < m[stk.back()])
                    r[stk.back()] = i, stk.pop_back();
                if (!stk.empty()) l[i] = stk.back();
                stk.push_back(i);
            }
            vector<int> pre(M + 1);
            for (int i = 1; i <= M; i++)
                pre[i] = pre[i - 1] + s[i];
            for (int i = 1; i <= M; i++)
                res = max(res, m[i] * (pre[r[i] - 1] - pre[l[i]]));
        }
    }
    cout << res << "\n";
    return 0;
}

标签:AtCoder,Beginner,int,311,nullptr,cin,long,++,vector
From: https://www.cnblogs.com/PHarr/p/17579648.html

相关文章

  • ABC311
    T1:FirstABC模拟代码实现n=int(input())s=input()A=B=C=Falseforiinrange(n):ifs[i]=='A':A=Trueifs[i]=='B':B=Trueifs[i]=='C':C=TrueifAandBandC:exit(print(i+1))......
  • Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)
    ToyotaProgrammingContest2023#4(AtCoderBeginnerContest311)A-FirstABC(atcoder.jp)记录一下\(ABC\)是否都出现过了然后输出下标#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signedmain(){ios::sync_with_stdio(false);cin.tie(n......
  • Atcoder ARC058E Iroha and Haiku
    题目中的式子转化一下即存在一位\(i\)使得到\(i\)时的后缀和存在\(X+Y+Z,Y+Z,Z\),再发现\(X+Y+Z\le17\),考虑状压。设\(f_{i,j}\)为填了\(i\)个数当前后缀和中存在的数的状态为\(j\)(只存\(0\simX+Y+Z\)的数是否存在)的方案数。考虑转移,则下一位可......
  • 「解题报告」Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)
    比赛地址:ToyotaProgrammingContest2023#4(AtCoderBeginnerContest311)-AtCoder后记:大家都太强了%%%,如果我做不出第四题就要掉分了。。。A-FirstABCA-FirstABC(atcoder.jp)找到第一个\(\texttt{A,B,C}\)三种字符都出现的位置。/*Thecodewaswrittenby......
  • Atcoder ARC058B Iroha and a Grid
    考虑从第\(b\)列与第\(b+1\)之间分开这个矩阵,钦定\((i,b)\)下一步必须走到\((i,b+1)\),可以发现这样是不会漏算或算重的。于是就可以用乘法原理算出这个\(i\)的贡献:\(\binom{(i-1)+(b-1)}{i-1}\times\binom{(n-i)+(m-b-1)}{n-i}\),左半部分的就......
  • ABC311 A~G
    \(Atcoder\)\(Beginner\)\(Contest\)\(311\)首先,ABC题是个人都会,这里就不说了其次,Ex我是人故我不会,这里也不说了DMD读错一个题害的我瞪了好久好久。。。。题意:给定一个矩阵,其中有些是墙(边界也是),最初人在\((2,2)\),每一次可以选择上下左右四个方向中的其中一个行走,直到撞......
  • 练习记录-AtCoder Beginner Contest 311-(A-E)
    写的还挺顺的F之后补A-FirstABC找abc三个字母什么时候出现了一次输出即可B-VacationTogether题意:最长的几个人一排里面均有时间#include<bits/stdc++.h>#defineclosestd::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)usingnamespacestd;typedeflon......
  • Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)——D
    https://atcoder.jp/contests/abc311/tasks/abc311_d思路题目说如果当前方向的下一个点能走,那么就一直走,否则才能转向。根据题意模拟即可,这道题的难点在于,碰到已经走过的点到底要不要走。如果当前方向走到底,其中的点之前全部都走过那么就不能再走了。我们用bfs模拟,对于能一直走......
  • ABC311(5)
    ABC311A.#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<int,int>PII;typedefunsignedlonglongULL;constintINF=0x3f3f3f3f;//无穷大constintMOD=1e9+7;//取余constintN=2e5+10;//初始N......
  • AtCoder Beginner Contest 311 A-E题解
    A-FirstABC题意给一个长度为N的仅由ABC三个字符组成的字符串S,问S中ABC三个字符第一次出现的位置的最大值。题解使用map<char,bool>判重,记录当前不同的字符串的个数cnt,当cnt等于3时,输出此时的下标+1作为答案。Code#include<bits/stdc++.h>usingnamespacestd;usingll......