zoukankan      html  css  js  c++  java
  • 2.4 综合训练

    A.Maximum Subrectangle(赛时完成)

    题意:求满足矩阵权值和 <= x ,且矩阵面积最大

    思路:矩阵权值和 = 横区间和 * 纵区间和

       预处理每个长度的最小区间和,对于每个长度的横区间和,二分查找最长符合条件纵区间和,对所有计算结果取max

    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 100;
    const int inf = 0x3f3f3f3f;
    ll arr[maxn];
    ll brr[maxn];
    ll la[maxn], lb[maxn];
    int main()
    {
        ll n, m ,x;
        scanf("%lld %lld", &n, &m);
        arr[0] = brr[0] = 0;
        memset(la, inf, sizeof la);
        memset(lb, inf, sizeof lb);
        for (int i = 1; i <= n; ++i)
        {
            scanf("%lld", &arr[i]);
            arr[i] = arr[i] + arr[i - 1];
        }
        for (int i = 1; i <= n; ++i)
        {
            for (int j = i; j <= n; ++j)
            {
                la[j - i + 1] = min(la[j - i + 1], arr[j] - arr[i - 1]);
            }
        }
        for (int i = 1; i <= m; ++i)
        {
            scanf("%lld", &brr[i]);
            brr[i] = brr[i] + brr[i - 1];
        }
        scanf("%lld", &x);
        for (int i = 1; i <= m; ++i)
        {
            for (int j = i; j <= m; ++j)
            {
                lb[j - i + 1] = min(lb[j - i + 1], brr[j] - brr[i - 1]);
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 1; j <= m; ++j)
            {
                if (la[i] * lb[j] <= x) ans = max(ans, i * j);
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    B.Mouse Hunt(赛后完成)

    题意:在房间中布置陷阱,询问无论老鼠从地出发都能被抓到的最小花费

    思路:每个连通块都是n点n边出度为1,因此对于每个连通块必定有环,且连通块路径有且只有一条,dfs跑环,找到环上权值最小的点,计算所有连通块的环上权值最小点的和

    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 3e5 + 100;
    const int inf = 0x3f3f3f3f;
    int val[maxn] ,to[maxn];
    int vis[maxn] ,vis1[maxn];
    int dfs(int rt)
    {
        if (vis[rt] != 0) return 0;
        vis1[rt]++;
        int ans = inf;
        if (vis1[rt] == 2)
        {
            if (to[rt] == rt) ans = val[rt];
            ans = min(ans, val[rt]);
            for (int i = to[rt]; i != rt; i = to[i])
            {
                ans = min(ans, val[i]);
            }
            return ans;
        }
        
        ans = min(ans, dfs(to[rt]));
        vis[rt] = 1;
        return ans == inf ? 0 : ans;
    }
    // n点n边且出度都为1 , 所以每个连通块必定有环 , 而且路径有且仅有一条
    int main()
    {
        int n;
        memset(vis, 0, sizeof vis);
        memset(vis1, 0, sizeof vis1);
        scanf("%d", &n);
        int sum = 0;
        for (int i = 1; i <= n; ++i) scanf("%d", &val[i]);
        for (int i = 1; i <= n; ++i) scanf("%d", &to[i]);
        for (int i = 1; i <= n; ++i)
        {
            if (vis[i] == 0)
            {
                sum += dfs(i);
            }
        }
        printf("%d
    ", sum);
        return 0;
    }
    View Code

    C.Psychos in a Line(赛后完成)

    题意:arr[i] > arr[i + 1] 第i个数字就可以把第i+1个数字消除掉,询问消除到没有数字可以消除所需要的步数

    思路:用单调栈从后往前维护一个单调递增栈,用dp[i]来维护i消除所有能够消除的数字所需要的最大步数

    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 100;
    const int inf = 0x3f3f3f3f;
    int arr[maxn];
    int ans[maxn];
    stack<int>s;
    int main()
    {
        int n;
        scanf("%d", &n);
        memset(ans, 0, sizeof ans);
        for (int i = 1; i <= n; ++i) scanf("%d", &arr[i]);
        for (int i = n; i >= 1; --i)
        {
            if (s.empty())
            {
                s.push(i);
                ans[i] = 0;
                continue;
            }
            if (arr[s.top()] > arr[i])
            {
                ans[i] = 0;
                s.push(i);
            }
            else
            {
                ans[i] = max(1, ans[s.top()]);
                // 第i个人肯定能杀死第s.top()个人
                s.pop();
                while (s.size() && arr[i] > arr[s.top()])
                {
                    ans[i] = max(ans[i] + 1, ans[s.top()]);
                    s.pop();
                }
                s.push(i);
            }
        }
        int val = 0;
        for (int i = 1; i <= n; ++i)
        {
            val = max(val, ans[i]);
            //printf("%d ", ans[i]);
        }
        //cout << endl;
        printf("%d
    ", val);
        return 0;
    }
    View Code

    D.Sequence Sorting(未完成)

    E.Lucky Transformation(赛时完成)

    题意:对于 i % 2 == 1 && arr[i] == 4 && arr[i + 1] == 7 ,arr[i + 1] = 4

          i % 2 == 1 && arr[i] == 4 && arr[i + 1] == 4 ,arr[i + 1] = 7

    思路:按题意模拟,考虑好特殊情况就行了

    #include<stdio.h>
    #include<string.h>
    using namespace std;
    const int maxn = 1e5 + 100;
    int arr[maxn];
    
    int main()
    {
        int n , k;
        scanf("%d %d", &n,&k);
        for (int i = 1; i <= n; ++i) scanf("%1d", &arr[i]);
        arr[0] = 0;
        for (int i = 1; i <= n; ++i)
        {
            if (k == 0) break;
            if (arr[i - 1] == 4 && arr[i] == 4 && arr[i + 1] == 7 && i % 2 == 0)
            {
                if (k % 2 == 1) arr[i] = 7;
                k = 0;
                break;
            }
            else if(arr[i - 1] == 4 && arr[i] == 7 && arr[i + 1] == 7 && i % 2 == 0)
            {
                if (k % 2 == 1) arr[i] = 4;
                k = 0;
                break;
            }
            else if (arr[i] == 4 && arr[i + 1] == 7 && i % 2 == 1)
            {
                arr[i + 1] = 4;
                k--;
            }
            else if (arr[i] == 4 && arr[i + 1] == 7 && i % 2 == 0)
            {
                arr[i] = 7;
                k--;
            }
        }
        for (int i = 1; i <= n; ++i)
        {
            printf("%d", arr[i]);
        }
        printf("
    ");
        return 0;
    }
    View Code

    F.President's Path(未完成)

  • 相关阅读:
    JQuery实现数组移除指定元素
    美团酒旅面经
    搜狗一面
    360面经
    头条面经
    搜狐笔试题
    kolakoski序列
    函数的节流
    隐藏元素的几种方法
    移动端适配与响应式布局
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/12262665.html
Copyright © 2011-2022 走看看