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

AtCoder Beginner Contest 339

时间:2024-02-06 20:33:43浏览次数:27  
标签:AtCoder 339 Beginner int dy1 dy2 dx2 dx1 mpp

AtCoder Beginner Contest 339

A - TLD

签到

B - Langton's Takahashi

发现步数和网格范围都不大,直接模拟即可

C - Perfect Bus

题目的合法性在于不能为负数,那么初始人数就有了二分性。

二分的找出初始的最小人数,然后跑一边即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define Acode ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
const int N = 4e6 + 10;
int n;
int a[N];

bool check(int mid)
{
    int x = mid;
    for (int i = 1; i <= n; i++)
    {
        x = x + a[i];
        if (x < 0)
            return false;
    }
    return true;
}

void solve()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    int l = 0, r = 1e15;
    while (l <= r)
    {
        int mid = l + r >> 1;
        if (check(mid))
            r = mid - 1;
        else
            l = mid + 1;
    }
    int x = l;
    for (int i = 1; i <= n; i++)
    {
        x = x + a[i];
    }
    cout << x << endl;
}

signed main()
{
    Acode;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

D - Synchronized Players

BFS的练习题,发现60的数据范围支持n^4的暴搜,所以我们就可以有x1,y1,x2,y2的状态来搜索,由于bfs队列内的不减性质,所以率先重合的次数就是答案

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define Acode ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
const int N = 110;
int n;
char mp[N][N];
int mpp[72][72][72][72];
int a[N];
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int vis[N][N];
// woc TLE
struct node
{
    int x1, y1;
    int x2, y2;
};
// map<array<int, 4>, int> mpp;
int xx1, xx2, yy1, yy2;
int ans = -1;

void bfs1()
{
    queue<pair<int, int>> q;
    q.push({xx1, yy1});
    vis[xx1][yy1] = 1;
    while (q.size())
    {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            int dx = x + dir[i][0];
            int dy = y + dir[i][1];
            if (dx < 1 || dx > n || dy < 1 || dy > n)
                continue;
            if (!vis[dx][dy])
            {
                vis[dx][dy] = 1;
                q.push({dx, dy});
            }
        }
    }
}

void bfs()
{
    memset(mpp, 0x3f, sizeof mpp);
    mpp[xx1][yy1][xx2][yy2] = 0;
    // mpp[{xx1, yy1, xx2, yy2}] = 0;
    // 特判-1 试一下算了
    queue<node> q;
    q.push({xx1, yy1, xx2, yy2});
    while (q.size())
    {
        auto it = q.front();
        q.pop();
        int x1 = it.x1;
        int y1 = it.y1;
        int x2 = it.x2;
        int y2 = it.y2;
        for (int i = 0; i < 4; i++)
        {
            int dx1 = x1 + dir[i][0];
            int dy1 = y1 + dir[i][1];
            int dx2 = x2 + dir[i][0];
            int dy2 = y2 + dir[i][1];
            if (mp[dx1][dy1] == '#' || dx1 <= 0 || dx1 > n || dy1 <= 0 || dy1 > n)
            {
                dx1 = x1;
                dy1 = y1;
            }
            if (mp[dx2][dy2] == '#' || dx2 <= 0 || dx2 > n || dy2 <= 0 || dy2 > n)
            {
                dx2 = x2;
                dy2 = y2;
            }
            // mpp[dx1][dy1][dx2][dy2]
            // mpp[x1][y1][x2][y2]
            if (mpp[dx1][dy1][dx2][dy2] > mpp[x1][y1][x2][y2] + 1)
            {
                mpp[dx1][dy1][dx2][dy2] = mpp[x1][y1][x2][y2] + 1;
                q.push({dx1, dy1, dx2, dy2});
            }
            if (dx1 == dx2 && dy1 == dy2)
            {
                ans = mpp[dx1][dy1][dx2][dy2];
                return;
            }
        }
    }
}
void solve()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            cin >> mp[i][j];
            if (mp[i][j] == 'P')
            {
                if (xx1 == 0)
                {
                    xx1 = i;
                    yy1 = j;
                }
                else
                {
                    xx2 = i;
                    yy2 = j;
                }
            }
        }
    }
    bfs1();
    if (vis[xx2][yy2] == 0)
    {
        cout << -1 << endl;
        return;
    }
    bfs();
    cout << ans << endl;
}

signed main()
{
    Acode;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

E - Smooth Subsequence

非常经典的dp,dp[i]的含义为选了第i个数,并且以它结尾的子序列的最长的长度,和LIS非常像。

那么这么想的话,我们是n^2的dp,不能通过。 观察发现就是每次就是从一个范围内,从其中的最大值来转移,所以可以用线段树来优化dp,开的类似与值域线段树,只关系值不关心它的位置。从这个值域内挑一个最大值来转移。

#include <bits/stdc++.h>
using namespace std;
#define Acode ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
#define endl '\n'
const int N = 1e6 + 10;
int a[N];
int dp[N];
// 先写n方的dp转移

struct info
{
    int mav;
};

struct node
{
    info val;
} seg[N << 2];

info operator+(const info &a, const info &b)
{
    info c;
    c.mav = max(a.mav, b.mav);
    return c;
}

void up(int id)
{
    seg[id].val = seg[id << 1].val + seg[id << 1 | 1].val;
}

// void build(int id, int l, int r) // id代表区间节点标号,l,r代表该区间节点的左右端点
// {
//     if (l == r)
//     {
//         seg[id].val = {a[l], 1};
//         return;
//     }
//     int mid = l + r >> 1;
//     build(id << 1, l, mid);
//     build(id << 1 | 1, mid + 1, r);
//     up(id);
// }

void change(int id, int l, int r, int x, int val)
{
    if (l == r)
    {
        seg[id].val = {val};
        return;
    }
    int mid = l + r >> 1;
    if (x <= mid)
        change(id << 1, l, mid, x, val);
    else
        change(id << 1 | 1, mid + 1, r, x, val);
    up(id);
}

info query(int id, int l, int r, int ql, int qr)
{
    if (ql <= l && r <= qr)
        return seg[id].val;
    int mid = l + r >> 1;
    if (qr <= mid) // 同理,查询区间属于左儿子就向左边去找 ,反之是右儿子
        return query(id << 1, l, mid, ql, qr);
    else if (ql > mid)
        return query(id << 1 | 1, mid + 1, r, ql, qr);
    else
        return query(id << 1, l, mid, ql, qr) + query(id << 1 | 1, mid + 1, r, ql, qr);
}

void solve()
{
    int n, d;
    cin >> n >> d;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
    {
        auto w = query(1, 1, N, max(1LL, a[i] - d), min(N, a[i] + d));
        int t = w.mav;
        dp[i] = max(dp[i], t + 1);
        auto it = query(1, 1, N, a[i], a[i]);
        int x = it.mav;
        if (x < dp[i])
        {
            change(1, 1, N, a[i], dp[i]);
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        // cerr << dp[i] << " ";
        ans = max(ans, dp[i]);
    }
    cout << ans << endl;
}

signed main()
{
    Acode;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

F - Product Equality

赛时没思路,晚上补

G - Smaller Sum

数据结构,晚上补

标签:AtCoder,339,Beginner,int,dy1,dy2,dx2,dx1,mpp
From: https://www.cnblogs.com/chenchen336/p/18010277

相关文章

  • Japan Registry Services (JPRS) Programming Contest 2024 (AtCoder Beginner Contes
    JapanRegistryServices(JPRS)ProgrammingContest2024(AtCoderBeginnerContest339)A-TLD代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__......
  • P3397 地毯
    原题链接二维差分的简单应用。作为学二维差分时的练手题很不错。主要代码:#include<bits/stdc++.h>usingnamespacestd;constintN=1002;inta[N][N];intmain(){ios::sync_with_stdio(false);intn,m;cin>>n>>m;for(inti=1;i<=m;i++){in......
  • AtCoder Beginner Contest 339
    A找到最后一个点的位置,使用substr函数。B模拟,记得边界是循环的。C容易发现答案为:\[\min_p(\sum_{i=1}^{p}a_i)+\sum_{i=1}^{n}a_i\]D由于不同状态数只有\(60^4\),容易搜索,但是我去吃饭了,所以没能快速切掉。E有一个显然的dp,然后考虑每一个\(a_i\)可以转移到\(a_j\)......
  • abc339 详解
    第一篇整场题解纪念我第一次AK的abc!A从后往前找到第一个'.'然后输出'.'到字符串结尾构成的字符串。#include<iostream>usingnamespacestd;intmain(intargc,constchar*argv[]){stringstr;cin>>str;intlen=(int)str.length();stri......
  • AtCoder Beginner Contest 330
    A-CountingPasses#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongusingvi=vector<int>;usingi32=int32_t;usingpii=pair<int,int>;#definempmake_pairconstintinf=1e9;i32main(){intn,l;......
  • AtCoder Beginner Contest 339
    基本情况A和C出的比较快但不能说秒了还是思考了几分钟的,然后B很奇怪我样例还有一些测试点都能过,但有些测试点就是过不了...A-TLD貌似没啥说的B-Langton'sTakahashi说实话现在还是不懂我的哪里错了很不科学啊,明明很多测试点都过了啊C-PerfectBus做题时的思路:要想求......
  • ABC339 F Product Equality 题解
    QuestionABC339FProductEquality给出一个序列\(A_1,A_2,\cdots,A_N\)计算数对\((i,j,k)\)满足\(A_i\timesA_j=A_k\)的个数\(A_i\le10^{1000}\)Solution思考\(A_i\)比较小的情况如果\(A_i\le1e9\)的,暴力枚举\(i,j\)然后用\(map\)查找\(A_i\timesA_j......
  • ABC339
    T1:TLD模拟代码实现s=input()a=s.split('.')print(a[-1])T2:Langton'sTakahashi模拟代码实现#include<bits/stdc++.h>#definerep(i,n)for(inti=0;i<(n);++i)usingnamespacestd;constintdi[]={-1,0,1,0};constintd......
  • ABC339总结
    ABC339Url:https://atcoder.jp/contests/abc339Time:1h30minComplete_time:2hB模拟,但是我考场上交了三次没过。因为我计算转移的时候把n,m写反了。x=(x+dx[dir]+m)%m;y=(y+dy[dir]+n)%n;x,y是坐标,dir是方向。我想错了,将x想成是横向移动了。下次要注意画图,不......
  • Japan Registry Services (JPRS) Programming Contest 2024 (AtCoder Beginner Contes
    //这一场我感觉有了新的蜕变思考问题也变了多种,3题(✌)A-TLD思路:题目本意 Youaregivenastring S, Printthelastsubstringwhen S issplitby .s给你一个字符串输出最后的点的网址(类似)的后缀,入坑点没有,题意简单。思路方法:最后一个‘.’为停止符号,倒的字符串......