0929字节笔试ak

字节的复活赛都输了,感觉身边拿字节offer都没走笔试程序,寄!

1:给定一个数组,使用双端队列按照顺序存(每次可以放到头或者尾),放完后双端队列能否非降序排列。

模拟+贪心:题目要求非降序,每次放的判断跟队列头尾比较就行,每次都要满足比头小或者比尾大。

n=(1e5),O(n)

#include "bits/stdc++.h"
using namespace std;
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n;
        scanf("%d", &n);
        deque<int> dq;
        bool flag = true;
        while (n--)
        {
            int tmp;
            scanf("%d", &tmp);
            if (flag)
            {
                if (dq.empty())
                    dq.push_back(tmp);
                else if (dq.front() >= tmp)
                    dq.push_front(tmp);
                else if (dq.back() <= tmp)
                    dq.push_back(tmp);
                else
                    flag = false;
            }
        }
        if (flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

2:给定n,从1开始,每a天执行一件事,每b天执行一件事,每c天执行一件事。问有多少天干了至少2件事。

三个集合相交:(a∩b)∪(a∩c)∪(b∩c)-2(a∩b∩c)

n=(1e5),O(n)

#include "bits/stdc++.h"
using namespace std;
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n, a, b, c;
        scanf("%d %d %d %d", &n, &a, &b, &c);
        int ab = a * b / gcd(a, b);
        int ac = a * c / gcd(a, c);
        int bc = b * c / gcd(b, c);
        int abc = ab * c / gcd(ab, c);
        int sum = 0;
        sum += n / ab;
        sum += n / ac;
        sum += n / bc;
        sum -= 2 * (n / abc);
        printf("%d\n", sum);
    }
    return 0;
}

3:给一个数组a(从1开始,每个元素都是[1,n]),可以从i到(i+1)和(i-1),开销是1。i到(i+a[i]),开销是abs(a[i]-a[i+a[i]))。从1开始,求到每个点的最小开销。

Dijkstra:抽象成图,跑一遍Dijkstra即可(太久没写最短路了,调了快50分钟)

n=(2e5),m是图中边的数目,该题m=3n=O(n)。O(mlog(m))=O(nlog(n))

#include "bits/stdc++.h"
using namespace std;
int main()
{
    int n;
    scanf("%d", &n);
    vector<int> arr(n + 1, 0);
    vector<int> dis(n + 1, n);
    vector<set<pair<int, int>>> edges(n + 1);
    for (int i = 1; i <= n; i++)
        scanf("%d", &arr[i]);
    for (int i = 1; i <= n; i++)
    {
        int j = i - 1;
        if (j >= 1)
            edges[i].insert(make_pair(j, 1));
        j = i + 1;
        if (j <= n)
            edges[i].insert(make_pair(j, 1));
        j = i + arr[i];
        if (j <= n)
            edges[i].insert(make_pair(j, abs(arr[i] - arr[j])));
    }
    auto dijkstra = [&](int s)
    {
        vector<bool> vis(n + 1, false);
        dis[s] = 0;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>
            pq;
        pq.push(make_pair(dis[s], s));
        while (!pq.empty())
        {
            auto top = pq.top();
            pq.pop();
            int d = top.first, u = top.second;
            if (vis[u])
                continue;
            vis[u] = true;
            for (auto iter : edges[u])
            {
                int v = iter.first, w = iter.second;
                if (dis[v] > d + w)
                {
                    dis[v] = d + w;
                    pq.push(make_pair(dis[v], v));
                }
            }
        }
    };
    dijkstra(1);
    for (int i = 1; i <= n; i++)
        printf("%d ", dis[i]);
    return 0;
}

4:给一个数组a,只有一个最大值的子数组称为完美子数组。求完美子数组的个数

复杂二分:从大到小遍历,每次遍历当前值的所有位置,用二分找到该位置能组成的完美子数组个数(左边prev(lower_bound),右边upper_bound)

n=(1e5)。O(nlog(n))

#include "bits/stdc++.h"
using namespace std;
using ll = long long;
int main()
{
    int n;
    scanf("%d", &n);
    vector<int> arr(n, 0);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    ll ans = 0;
    map<int, set<int>> ump;
    set<int> st;
    for (int i = 0; i < n; i++)
        ump[arr[i]].insert(i);
    for (auto iter = ump.rbegin(); iter != ump.rend(); iter++)
    {
        for (auto index : iter->second)
            st.insert(index);
        for (auto index : iter->second)
        {
            auto l_iter = st.lower_bound(index);
            auto r_iter = st.upper_bound(index);
            int l = index, r = index;
            if (l_iter == st.begin())
                l = index + 1;
            else
                l = index - *(--l_iter);
            if (r_iter == st.end())
                r = n - index;
            else
                r = *r_iter - index;
            ans += ll(l) * r;
        }
    }
    cout << ans << endl;
    return 0;
}

带哨兵节点的版本

#include "bits/stdc++.h"
using namespace std;
using ll = long long;
int main()
{
    int n;
    scanf("%d", &n);
    vector<int> arr(n, 0);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    ll ans = 0;
    map<int, set<int>> ump;
    set<int> st;
    // 哨兵节点
    st.insert(-1);
    st.insert(n);
    for (int i = 0; i < n; i++)
        ump[arr[i]].insert(i);
    for (auto iter = ump.rbegin(); iter != ump.rend(); iter++)
    {
        for (auto index : iter->second)
            st.insert(index);
        for (auto index : iter->second)
            ans += ll(index - *(--st.lower_bound(index))) * (*st.upper_bound(index) - index);
    }
    cout << ans << endl;
    return 0;
}

#25秋招##字节笔试#
全部评论
捞 第三题为啥不能用动态规划啊
1 回复 分享
发布于 昨天 21:22 新疆
佬 第四题我用滑动窗口做为什么样例过了提交只有5%呀
点赞 回复 分享
发布于 昨天 21:15 辽宁
数组里面的最大值我是用max_element判断的,如果等于当前数组里的最大值就break
点赞 回复 分享
发布于 昨天 21:17 辽宁
第三题原来i可以到i-1啊,没考虑到这种情况,直接零蛋
点赞 回复 分享
发布于 昨天 21:18 浙江
第四题太天才了
点赞 回复 分享
发布于 昨天 23:31 广东
第一题只存左右节点可以吗,我初始化最大最小值之后百分之0😭
点赞 回复 分享
发布于 今天 00:21 山西

相关推荐

昨天 13:47
门头沟学院 Java
#腾讯&nbsp;#阿里&nbsp;#字节
投递小米集团等公司10个岗位 >
点赞 评论 收藏
分享
昨天 21:13
华南理工大学 C++
#字节笔试#四道编程&nbsp;C++解法第一题&nbsp;木板可收集雨水的最大量int&nbsp;main()&nbsp;{int&nbsp;n;cin&nbsp;&gt;&gt;&nbsp;n;priority_queue&lt;int&gt;&nbsp;pq;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;++i)&nbsp;{int&nbsp;x;cin&nbsp;&gt;&gt;&nbsp;x;pq.push(x);}pq.pop();cout&nbsp;&lt;&lt;&nbsp;static_cast&lt;long&nbsp;long&gt;(n&nbsp;-&nbsp;1)&nbsp;*&nbsp;pq.top();}第二题&nbsp;数组按顺序插入双端队列可否保证有序(非严格递增)int&nbsp;main()&nbsp;{int&nbsp;T,&nbsp;n;cin&nbsp;&gt;&gt;&nbsp;T;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;T;&nbsp;++i)&nbsp;{cin&nbsp;&gt;&gt;&nbsp;n;vector&lt;int&gt;&nbsp;nums(n&nbsp;-&nbsp;1);int&nbsp;l,&nbsp;r;cin&nbsp;&gt;&gt;&nbsp;l;&nbsp;r&nbsp;=&nbsp;l;for&nbsp;(auto&amp;amp;&nbsp;x&nbsp;:&nbsp;nums)cin&nbsp;&gt;&gt;&nbsp;x;bool&nbsp;flag&nbsp;=&nbsp;true;for&nbsp;(auto&nbsp;x&nbsp;:&nbsp;nums)&nbsp;{if&nbsp;(x&nbsp;&lt;=&nbsp;l)l&nbsp;=&nbsp;x;else&nbsp;if&nbsp;(x&nbsp;&gt;=&nbsp;r)r&nbsp;=&nbsp;x;else&nbsp;{flag&nbsp;=&nbsp;false;break;}}cout&nbsp;&lt;&lt;&nbsp;(flag&nbsp;?&nbsp;&amp;quot;YES\n&amp;quot;&nbsp;:&nbsp;&amp;quot;NO\n&amp;quot;);}}第三题&nbsp;n天内做超过两件事的天数int&nbsp;main()&nbsp;{using&nbsp;ll&nbsp;=&nbsp;long&nbsp;long;int&nbsp;T,&nbsp;n,&nbsp;a,&nbsp;b,&nbsp;c;cin&nbsp;&gt;&gt;&nbsp;T;for&nbsp;(int&nbsp;k&nbsp;=&nbsp;0;&nbsp;k&nbsp;&lt;&nbsp;T;&nbsp;++k)&nbsp;{cin&nbsp;&gt;&gt;&nbsp;n&nbsp;&gt;&gt;&nbsp;a&nbsp;&gt;&gt;&nbsp;b&nbsp;&gt;&gt;&nbsp;c;ll&nbsp;Nab&nbsp;=&nbsp;lcm&lt;ll,&nbsp;ll&gt;(a,&nbsp;b),&nbsp;Nbc&nbsp;=&nbsp;lcm&lt;ll,&nbsp;ll&gt;(b,&nbsp;c),&nbsp;Nac&nbsp;=&nbsp;lcm&lt;ll,&nbsp;ll&gt;(a,&nbsp;c);ll&nbsp;N&nbsp;=&nbsp;lcm&lt;ll,&nbsp;ll&gt;(Nab,&nbsp;c);int&nbsp;res&nbsp;=&nbsp;n&nbsp;/&nbsp;Nab&nbsp;+&nbsp;n&nbsp;/&nbsp;Nbc&nbsp;+&nbsp;n&nbsp;/&nbsp;Nac&nbsp;-&nbsp;n&nbsp;/&nbsp;N&nbsp;*&nbsp;2;cout&nbsp;&lt;&lt;&nbsp;res&nbsp;&lt;&lt;&nbsp;&#39;\n&#39;;}}第四题&nbsp;最大值不重复的子数组个数(没做出来,通过10%)int&nbsp;main()&nbsp;{int&nbsp;n;cin&nbsp;&gt;&gt;&nbsp;n;vector&lt;int&gt;&nbsp;nums(n);for&nbsp;(auto&amp;amp;&nbsp;x&nbsp;:&nbsp;nums)cin&nbsp;&gt;&gt;&nbsp;x;using&nbsp;pii&nbsp;=&nbsp;pair&lt;int,&nbsp;int&gt;;stack&lt;pii&gt;&nbsp;stk;queue&lt;pii&gt;&nbsp;q;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;++i)&nbsp;{int&nbsp;x&nbsp;=&nbsp;nums[i];while&nbsp;(!stk.empty()&nbsp;&amp;amp;&amp;amp;&nbsp;stk.top().first&nbsp;&lt;&nbsp;x)&nbsp;{stk.pop();}if&nbsp;(!stk.empty()&nbsp;&amp;amp;&amp;amp;&nbsp;stk.top().first&nbsp;==&nbsp;x)&nbsp;{q.emplace(stk.top().second,&nbsp;i);stk.pop();}stk.emplace(x,&nbsp;i);}long&nbsp;long&nbsp;res&nbsp;=&nbsp;(long&nbsp;long)n&nbsp;*&nbsp;(1&nbsp;+&nbsp;n)&nbsp;/&nbsp;2;while&nbsp;(!q.empty())&nbsp;{auto&nbsp;[l,&nbsp;r]&nbsp;=&nbsp;q.front();&nbsp;q.pop();int&nbsp;x&nbsp;=&nbsp;nums[l];int&nbsp;i&nbsp;=&nbsp;l&nbsp;-&nbsp;1,&nbsp;j&nbsp;=&nbsp;r&nbsp;+&nbsp;1;while&nbsp;(i&nbsp;&gt;=&nbsp;0&nbsp;&amp;amp;&amp;amp;&nbsp;nums[i]&nbsp;&lt;&nbsp;x)--i;while&nbsp;(j&nbsp;&lt;&nbsp;n&nbsp;&amp;amp;&amp;amp;&nbsp;nums[j]&nbsp;&lt;&nbsp;x)++j;res&nbsp;-=&nbsp;(long&nbsp;long)(l&nbsp;-&nbsp;i)&nbsp;*&nbsp;(j&nbsp;-&nbsp;r);}cout&nbsp;&lt;&lt;&nbsp;res;}
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
头像
昨天 21:03
西北大学 Java
点赞 评论 收藏
分享
本菜鸟哪见过这种场面一群保研佬
我已成为0offer的糕手:说明你太有人脉了
点赞 评论 收藏
分享
3 4 评论
分享
牛客网
牛客企业服务