• 牛客小白月赛22


    操作序列

    思路

    这题我觉得用map模拟其实很好,但是如果用线段树的话也还行,主要是线段树不是很会。

    为了避免不必要的开销,map使用find函数,打印的时候用map.begin()->second就可以了啦。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    int main()
    {
        map<ll,ll> mp;
        int n;
        scanf("%d",&n);
        char ch;
        ll num1,num2;
        while (n--) {
            scanf("%lld%c",&num1,&ch);
            if (ch==' ') {
                scanf("%lld",&num2);
                bool flag=true;
                for (int i=num1-30;i<=num1+30;i++) {
                    if (mp.find(i)!=mp.end()) {
                        flag=false;
                        break;
                    }
                }
                if (flag) {
                    mp[num1]=num2;
                }
            }
            else {
                if (num1==-1) {
                    if (mp.begin()!=mp.end()) {
                        printf("%lld
    ",mp.begin()->second);
                        mp.erase(mp.begin());
                    }
                    else {
                        printf("skipped
    ");
                    }
                }
                else {
                    if (mp.find(num1)==mp.end()) {
                        printf("0
    ");
                    }
                    else {
                        printf("%lld
    ",mp[num1]);
                    }
                }
            }
        }
        return 0;
    }
    

    树上子链

    思路

    这题他们说是树形dp模板题,定义dp[i]是以i为根节点,不同时携带左右子树的值最大链。

    这样对于每一个根节点就可以判断加上左右子树之后的最大值了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn=1e5+10;
    vector<int> g[maxn];
    int w[maxn];
    ll dp[maxn],ans=-(1<<30);
    
    void dfs(int u,int f) {
        dp[u]=w[u];
        for (auto v:g[u]) {
            if (v==f) {
                continue;
            }
            dfs(v,u);
            ans=max(ans,dp[u]+dp[v]);
            dp[u]=max(dp[u],dp[v]+w[u]);
        }
        ans=max(ans,dp[u]);
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for (int i=1;i<=n;i++) {
            scanf("%d",&w[i]);
        }
        int u,v;
        for (int i=0;i<n-1;i++) {
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1,0);
        printf("%lld
    ",ans);
        return 0;
    }
    

    货物种类

    思路

    这题就是暴力啦,所有点做排列,10!是3e6左右,10组问题不大。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    int x[15],y[15],a[15];
    inline int getDistance(int i,int j) {
        return abs(x[i]-x[j])+abs(y[i]-y[j]);
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while (t--) {
            int sx,sy;
            scanf("%d%d",&sx,&sy);
            scanf("%d%d",&sx,&sy);
            int n;
            scanf("%d",&n);
            for (int i=0;i<n;i++) {
                scanf("%d%d",&x[i],&y[i]);
                a[i]=i;
            }
            a[n]=n;
            x[n]=sx;
            y[n]=sy;
            int ans=1<<30;
            do {
                int c=getDistance(a[0],n)+getDistance(a[n-1],n);
                for (int i=0;i<n-1;i++) {
                    // printf("%d %d %d    ",a[i],a[i+1],getDistance(a[i],a[i+1]));
                    c+=getDistance(a[i],a[i+1]);
                }
                // printf("
    %d
    ",c);
                ans=min(ans,c);
            } while (next_permutation(a,a+n));
            printf("The shortest path has length %d
    ",ans);
        }
        return 0;
    }
    

    仓库选址

    思路

    这题暴力都能过,没错就是你想的暴力,n^4,但是这题正解应该包括有前缀和和数学两种解法。

    前缀和就很简单啦。

    先求出来第一列,所有行的答案,然后递推其他点的答案。

    关于递推,假设当前点是(x,y) ,下一个点是(x,y+1),则矩阵[m,x] (右上角的点,左下角(1,1))中的每个点到(x,y+1)的x距离都+1,但是y距离不变;矩阵[x+1,1]到[m,n]中的每个点x的距离都减一。

    当我们知道(x,y)的答案之后,左边的矩阵总共需要走几次就加几,右边的矩阵需要走几次就减几就可以啦。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=105;
    ll a[maxn][maxn],sum[maxn][maxn],cnt[maxn][maxn],c[maxn][maxn];
    int main()
    {
        ll t;
        scanf("%lld",&t);
        while (t--) {
            ll n,m;
            scanf("%lld%lld",&n,&m);
            for (ll i=1;i<=m;i++) {
                for (ll j=1;j<=n;j++) {
                    scanf("%lld",&a[i][j]);
                }
            }
            for (ll i=1;i<=m;i++) {
                for (ll j=1;j<=n;j++) {
                    cnt[i][j]=cnt[i][j-1]+cnt[i-1][j]-cnt[i-1][j-1]+a[i][j];
                    a[i][j]=a[i][j]*(abs(i-1)+abs(j-1));
                    sum[i][j]=sum[i][j-1]+sum[i-1][j]+a[i][j]-sum[i-1][j-1];
                }
            }
            c[1][1]=sum[m][n];
            ll ans=min((ll)(1<<30),c[1][1]);
            for (ll i=2;i<=m;i++) {
                c[i][1]=c[i-1][1]-(cnt[m][n]-cnt[i-1][n])+cnt[i-1][n];
                ans=min(c[i][1],ans);
            }
            for (ll i=1;i<=m;i++) {
                for (ll j=2;j<=n;j++) {
                    c[i][j]=c[i][j-1]-(cnt[m][n]-cnt[m][j-1])+cnt[m][j-1];
                    ans=min(c[i][j],ans);
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    TensorFlow中的基本概念
    理解 tf.Variable、tf.get_variable以及范围命名方法tf.variable_scope、tf.name_scope
    深度神经网络关键词解释
    [python] os.path.join() 与 sys.path
    Git 遇到的坑
    [转] 资深程序员得到的职场经验教训
    VS CODE 快捷键
    解决VS Code使用code runner开发Python乱码问题
    熵,条件熵,互信息,交叉熵
    Visual Studio Code 支持TensorFlow配置支持
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/12401865.html
Copyright © 2020-2023  润新知