其他分享
首页 > 其他分享> > AtCoder Beginner Contest 253 A - E

AtCoder Beginner Contest 253 A - E

作者:互联网

传送门

A - Median?

找中间数

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn];

int main()
{
    for(int i=0; i<3; i++) cin >> num[i];
    int a = num[1];
    sort(num, num + 3);
    if(a == num[1]) cout << "Yes" << endl;
    else cout << "No" << endl;

    return 0;
}

B - Distance Between Tokens

找起点和终点的曼哈顿距离

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i=0; i<n; i++)
        cin >> s[i];
    int sx = -1, sy, ex, ey;
    int cnt = 0;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(s[i][j] == 'o')
            {
                if(cnt == 0)
                {
                    sx = i;
                    sy = j;
                    cnt++;
                }
                if(cnt == 1)
                {
                    ex = i;
                    ey = j;
                }
            }
        }
    }
    
    
    cout << abs(ex - sx) + abs(ey - sy) << endl;

    return 0;
}

C - Max - Min Query

可以直接用 map 维护就好了

我是用 set 维护,然后 map 判断什么时候删除和增加

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    set<int>s;
    map<int, int>vis;
    while(q--)
    {
        int t;
        cin >> t;
        if(t == 1)
        {
            int x;
            cin >> x;
            if(++vis[x] == 1) s.insert(x);
        }
        else if(t == 2)
        {
            int x, cc;
            cin >> x >> cc;
            int way = min(cc, vis[x]);
            vis[x] -= way;
            if(vis[x] == 0 && way != 0) s.erase(x);
        }
        else
        {
            auto it = s.end();
            it--;
            cout << (*it - *s.begin()) << endl;
        }
    }
    return 0;
}

D - FizzBuzz Sum Hard

我写的极其复杂

直接等差数列,减去 a 的倍数,减去 b 的倍数,加上 a 和 b 的公倍数

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll n, a, b;
    cin >> n >> a >> b;
    ll ab = a / __gcd(a, b) * b;
    ll t = n / ab;
    ll sum = 0;
    if(t)
    {
        sum += (1 + ab) * ab / 2;
        sum -= ab * (ab / a - 1) / 2;
        sum -= ab * (ab / b - 1) / 2;
        sum -= ab;
        sum *= t * t;
    }
    // cout << sum << endl;
    if(n % ab)
    {
        ab = t * ab;
        ll ta = (n - ab) / a;
        ll tb = (n - ab) / b;
        sum -= (ab + a + ab + ta * a) * ta / 2;
        sum -= (ab + b + ab + tb * b) * tb / 2;
        sum += (1 + ab + n) * (n - ab) / 2;
    }
    cout << sum << endl;
    return 0;
}

E - Distance Sequence

dp

\(dp[i][j]\) 表示第 \(i\) 个数字是 \(j\) 的时候的方案数

状态转移:\(dp[i][j] = \sum{}{} dp[i-1][v]\),\(v\) 表示当第 \(i\) 个数字为 \(j\) 时,第 \(i - 1\) 个数字满足相差绝对值不小于 \(k\) 的数字

纯转移的话复杂度很高,可以考虑用前缀和处理一下,复杂度为 \(O(nm)\)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 1010;
const ll inf = 1e17 + 10;
const ll mod = 998244353;
ll dp[maxn][maxn * 5];
ll sum[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll n, m, k;
    cin >> n >> m >> k;
    for(int i=1; i<=m; i++) {dp[0][i] = 1; sum[i] = sum[i-1] + 1;}
    for(int i=1; i<n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            ll l = j - k;
            ll r = j + k;
            l++;
            r--;
            l = max(1ll, l);
            r = min(m, r);
            dp[i][j] = (mod + sum[m] - max(0ll, sum[r] - sum[l-1])) % mod;
        }
        for(int j=1; j<=m; j++)
            sum[j] = sum[j-1] + dp[i][j];
        // cout << "now: ";
        // cout << sum[m] << endl;
    }
    cout << sum[m] % mod << endl;
    return 0;
}

F - Operations on a Matrix

F 到现在都没过,我的想法是对于每次询问,找到最近的改变行的操作,然后将那个坐标的差值用 map 储存起来

然后列的叠加还是用树状数组维护,但是现在死活过不去

标签:AtCoder,const,Beginner,int,ll,cin,maxn,253,include
来源: https://www.cnblogs.com/dgsvygd/p/16323701.html