• 第 2 场周赛


    3626. 三元一次方程

    签到。

    暴力思路是三重枚举,可优化至两重枚举。

    int n;
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            cin>>n;
            bool ok=false;
            
            for(int i=0;3*i<=n && !ok;i++)
                for(int j=0;3*i+5*j<=n && !ok;j++)
                {
                    int k=n-3*i-5*j;
                    if(k % 7 == 0)
                    {
                        ok=true;
                        cout<<i<<' '<<j<<' '<<k/7<<endl;
                    }
                }
            
            if(!ok) puts("-1");
        }
        //system("pause");
        return 0;
    }
    

    3627. 最大差值

    贪心。

    (k)次操作,每次可选定一对元素((a_i,a_j)),使得其中一个增加(c),另一个减少(c)(0 le c le a_i)

    最小值最终一定为(0),最大值初值可设为序列中的最大值。

    显然每次操作的(c)越大越好,于是(c)依次取除去最大值后序列中的前(k)大值即为最优。

    const int N=2e5+10;
    int a[N];
    int n,k;
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            cin>>n>>k;
    
            for(int i=0;i<n;i++) cin>>a[i];
    
            sort(a,a+n,greater<int>());
    
            LL res=a[0];
            for(int i=1;i<=k;i++) res+=a[i];
            cout<<res<<endl;
        }
        //system("pause");
        return 0;
    }
    

    3628. 边的删减

    • 对某一个点(i),若(d_i)不变,则在最短路树中从(1)(i)的所有边必须被保留。
    • 每保留一条边,可以让一个点的(d_i)保持不变。
    • (dist[u]+w(u ightarrow v) = dist[v])说明是最短路树上的边。

    若想(d_i)保持不变的点尽量多,从最短路树的根节点(1)开始任意选一个包含(k)条边的连通块即可,这样可使得(k+1)个点的(d_i)保持不变。

    于是记录最短路树中的所有边的编号,保留出队的前(k)条边存入(res)数组中即可。

    Dijkstra算法每个节点仅出队一次,出队顺序满足拓扑序,于是优先出队的前(k)条边一定是属于同一个连通块的。

    const int N=1e5+10;
    struct Node
    {
        int v;
        LL dis;
        int idx;
        bool operator>(const Node &W) const
        {
            return dis > W.dis;
        }
    };
    vector<Node> g[N];
    LL dist[N];
    bool vis[N];
    int n,m,k;
    vector<int> res;
    
    void dijkstra()
    {
        memset(dist, 0x3f, sizeof dist);
        dist[1] = 0;
        priority_queue<Node, vector<Node>, greater<Node>> heap;
        heap.push({1,0,0});
    
        while (heap.size())
        {
            int t=heap.top().v, idx=heap.top().idx;
            heap.pop();
    
            if (vis[t]) continue;
            vis[t] = true;
            
            if(idx && res.size() < k) res.pb(idx);
    
            for(int i=0;i<g[t].size();i++)
            {
                int j = g[t][i].v, w=g[t][i].dis, idx=g[t][i].idx;
                if (dist[j] > dist[t] + w)
                {
                    dist[j] = dist[t] + w;
                    heap.push({j, dist[j], idx});
                }
            }
        }
    }
    
    int main()
    {
        cin>>n>>m>>k;
    
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            g[a].pb({b,c,i});
            g[b].pb({a,c,i});
        }
        
        dijkstra();
        
        cout<<res.size()<<endl;
        
        for(auto &t : res)
            cout<<t<<' ';
        cout<<endl;
    
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    如何使用Redis实现分布式缓存
    如何使用Swagger生成API文档
    Asp.Net Core WebApi入门
    如何使用Entity Framework Core实现增删改查(CRUD)
    Microsoft.Extensions.DependencyInjection入门
    什么是中介者模式
    什么是依赖注入
    什么是事件总线
    点滴智慧
    并查集
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14855049.html
Copyright © 2020-2023  润新知