codeforce#933 题解

E. Rudolf and k Bridges

题意不讲了,不如去题干看图。
传统dp,每个点有两个选择,那么建桥要么不建。需要注意的是在状态转移的时候,桥是有长度的,如果不建需要前d格中建桥花费最少的位置作为状态转移的初态。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <set>
#include <unordered_set>
#include <map>
#include <queue>
 
#define IOS     ios::sync_with_stdio(0);cin.tie(0);
#define mem(A,B) memset(A,B,sizeof(A));
#define rep(index,start,end) for(int index = start;index < end; index ++)
#define drep(index,start,end) for(int index = start;index >= end; index --)
 
using namespace std;
 
typedef long long ll;

const int maxn = 2e5+5;

struct contianer {
    private:
        int step;
        int pos = 0;
        ll loop[maxn];
        multiset<ll> store;

    public:
        contianer(int step):step(step) {}
        
        void add(ll x) {
            int now = pos % step;
            // need to remove
            if (pos >= step) {
                store.erase(store.find(loop[now]));
            }
            
            loop[now] = x;
            store.insert(x);
            pos ++;
        }
        
        /**
          * get min number
         */
        ll get() {
            return *store.begin();
        }
        
        void setStep(int s);
        
        void clear();
};

void contianer::setStep(int s) {
    step = s;
}

void contianer::clear() {
    store.clear();
    pos = 0;
}

ll sum[128];
int store[maxn];
ll dp[maxn][2];
int main() {
    IOS
    
    int t;
    cin>>t;
    while(t--) {
        int n,m,k,d;
        cin>>n>>m>>k>>d;
        contianer heap(d);
        
        sum[0] = 0LL;
        // input and dp
        rep(_,0,n) {
            // input
            rep(i,0,m) cin>>store[i];
            // init
            heap.clear();
            heap.add(store[0] + 1);
            dp[0][0] = dp[0][1] = store[0] + 1;
            // dp
            rep(i,1,m-1) {
                ll min_cost = heap.get();
                dp[i][0] = min_cost;
                dp[i][1] = min(dp[i-1][0], min_cost) + store[i] + 1;
//                cout<<"dp["<<i<<"][0]:"<<dp[i][0]<<" dp["<<i<<"][1]:"<<dp[i][1]<<endl;
                
                heap.add(dp[i][1]);
            }
            // cost
            sum[_ + 1] = min(dp[m-2][1], dp[m-2][0]) + 1LL;
//            cout<<sum[_+1]<<endl;
        }
        // pre sum
        rep(i,1,n+1) sum[i] += sum[i-1];
        // the k min
        ll ans = sum[k] - sum[0];
        rep(i,k+1,n+1) {
            ans = min(ans, sum[i] - sum[i-k]);
        }
        // cout
        cout<<ans<<endl;
    }
    
    return 0;
}

F. Rudolf and Imbalance

求两数和的plus版本。给出数组a,现在要分别从d和f挑选一个数相加后放入a,使得所有 a i + 1 − a i a_{i+1} - a_i ai+1ai中最大值尽可能小。
显然,我们只要找到在没有挑选插入前 a i + 1 − a i a_{i+1} - a_i ai+1ai的最大值以及 i i i的值,然后构造 a i + 1 > d + f > a i a_{i+1} > d+f > a_i ai+1>d+f>ai,就可以破坏最大值。且 d + f = a i + 1 + a i 2 d+f = \frac {a_{i+1} + a_i}{2} d+f=2ai+1+ai时,能将最大值分割的尽可能小。
其中,如果最大值和第二大值一样,那么无论怎么分割都改变不了最大值,可以直接输出。
至于怎么让 d + f d+f d+f尽可能靠近中点就不细说了,固定d然后二分搜索f。这里我脑干缺失写了个int target = abs(aim - commonA);我是真的睿智

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <set>
#include <map>
#include <queue>

#define IOS     ios::sync_with_stdio(0);cin.tie(0);
#define mem(A,B) memset(A,B,sizeof(A));
#define rep(index,start,end) for(int index = start;index < end; index ++)
#define drep(index,start,end) for(int index = start;index >= end; index --)

using namespace std;

typedef long long ll;

const int maxn = 2e5+5;

struct record{
    int val;
    int ind;
};

int store[maxn/2];
record dif[maxn/2];
int d[maxn], f[maxn];
bool cmp(const record& a, const record& b) {
    return a.val < b.val;
}
int abs(int a) {
    if (a<0) return -a;
    else return a;
}
int main() {
    IOS
    
    int t;
    cin>>t;
    while(t--) {
        int n,m,k;
        cin>>n>>m>>k;
        
        int pos = 0;
        cin>>store[0];
        rep(i,1,n) {
            cin>>store[i];
            dif[pos].ind = i;
            dif[pos ++].val = store[i] - store[i-1];
        }
        sort(dif, dif+pos,cmp);
//        rep(i,0,pos) cout<<dif[i].val<<endl;
        
        int len_d , len_f;
        if (m < k) {
            rep(i,0,m) cin>>d[i];
            sort(d, d+m);
            len_d = m;
            rep(i,0,k) cin>>f[i];
            sort(f, f+k);
            len_f = k;
        } else {
            rep(i,0,m) cin>>f[i];
            sort(f,f+m);
            len_f = m;
            rep(i,0,k) cin>>d[i];
            sort(d,d+k);
            len_d = k;
        }
        
        if (pos > 2 && dif[pos-1].val == dif[pos-2].val) {
            cout<<dif[pos-1].val<<endl;
            continue;
        }
        
        int sup = store[dif[pos-1].ind];
        int inf = store[dif[pos-1].ind - 1];
        int aim = inf + (sup - inf)/2;
        int minn = dif[pos-1].val;
        rep(i,0,len_d) {
            int commonA = d[i];
            if (commonA >= sup) break;
            
            int target = aim - commonA;
//            cout<<"d[i]:"<<d[i]<<" target:"<<target<<endl;
            auto it = upper_bound(f, f+len_f-1, target);
//            cout<<"it:"<<it<<endl;
            
            int commonB = *it;
//            cout<<"find:"<<commonB<<endl;
            int num = commonA + commonB;
            if (inf<num && num<sup)
                minn = min(minn, max(sup - num ,num - inf));
            
            if (it != f) {
                commonB = *(it-1);
                num = commonA + commonB;
                if (inf<num && num<sup)
                    minn = min(minn, max(sup - num ,num - inf));
            }
        }
        /*
        if (d[0] + f[0] < store[0]) {
            aim = store[0];
            rep(i,0,len_d) {
                int commonA = d[i];
                if (commonA >= aim) break;
                
                int target = abs(aim - commonA);
                auto it = lower_bound(f, f+len_f-1, target-1);
                
                int commonB = *it;
                cout<<"commonA:"<<commonA<<" commonB:"<<commonB<<" target:"<<target<<endl;
                int num = commonA + commonB;
                if (num < store[0])
                    minn = min(minn, store[0] - num);
                
                if (it != f) {
                    commonB = *(it-1);
                    num = commonA + commonB;
                    if (num < store[0])
                        minn = min(minn, store[0] - num);
                }
            }
        }
        
        aim = store[n-1];
        if (d[len_d-1] + f[len_f-1] > aim)
            rep(i,0,len_d) {
                int commonA = d[i];
                
                int target = abs(aim - commonA);
                auto it = upper_bound(f, f+len_f-1, target+1);
                
                int commonB = *it;
                int num = commonA + commonB;
                if (num > aim) {
                    minn = min(minn, num - aim);
                }
                if(it == f) break;
            }
        */
        cout<<max(minn, pos>=2? dif[pos-2].val : 0)<<endl;
    }
    
    return 0;
}

G. Rudolf and Subway

很好的图论使我小脑萎缩
边染色,求A->B最少经过几种颜色。其中相同颜色的边一定构成连通图。
机智如我并没有按照题解中加边的思路,而是采用合并点的方式,从颜色的维度处理。将相同颜色的边视为从同一个点出发(因为相同颜色内移动不会影响结果,只有移动到新的颜色上才会影响结果),从而将问题转化为最短路。采用bfs那么首先经过的颜色一定是最短路,从而可以作为优化的条件。
此外由于是边染色,所有可能一个点会被多个颜色所合并。如果在颜色A的合并点里走到了点v,同时v又连接B、C等颜色的边,虽然后续B、C颜色的合并也会重新遍历v的边,但是由于bfs的特性此时的遍历不会影响已经过的颜色A,也不会加入新的颜色(因为v涉及的所有颜色都在颜色A的合并点中加入到了队列),所以图中的每个点只需要访问一次,不需要重复访问。
没有这个优化会T 嘤嘤嘤

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <set>
#include <map>
#include <queue>

#define IOS     ios::sync_with_stdio(0);cin.tie(0);
#define mem(A,B) memset(A,B,sizeof(A));
#define rep(index,start,end) for(int index = start;index < end; index ++)
#define drep(index,start,end) for(int index = start;index >= end; index --)

using namespace std;

typedef long long ll;

const int maxn = 2e5+5;

struct node{
    int to;
    int color;
};

queue<int> Q;
bool vis[maxn],visNode[maxn];
int dis[maxn];
set<int> colors;
set<int> colorSet[maxn];
vector<node> adj[maxn];
int main() {
    IOS
    cout.tie(0);
    
    int t;
    cin>>t;
    while(t--) {
        for(auto it=colors.begin();it!=colors.end();it++){
            vis[*it] = false;
            colorSet[*it].clear();
        }
        colors.clear();
        
        int n,m;
        cin>>n>>m;
        rep(i,0,n+1) {
            adj[i].clear();
            visNode[i] = false;
        }
        
        rep(i,0,m) {
            int commonA,commonB,color;
            cin>>commonA>>commonB>>color;
            adj[commonA].push_back({commonB, color});
            adj[commonB].push_back({commonA, color});
            
            colorSet[color].insert(commonA);
            colorSet[color].insert(commonB);
            
            colors.insert(color);
        }
        int commonA,commonB;
        cin>>commonA>>commonB;
        if (commonA==commonB) {
            cout<<0<<endl;
            continue;
        }
        
        for(auto it=colors.begin();it!=colors.end();it++)
            dis[*it] = INT_MAX;
        
        visNode[commonA] = true;
        rep(i,0,adj[commonA].size()) {
            node edge = adj[commonA][i];
            if (!vis[edge.color]) {
                Q.push(edge.color);
//                cout<<"push color:"<<edge.color<<endl;
                dis[edge.color] = 1;
                vis[edge.color] = true;
            }
        }
        while(!Q.empty()) {
            int now = Q.front();
//            cout<<"color:"<<now<<" dis:"<<dis[now]<<endl;
            Q.pop();
            
            for(int v : colorSet[now]) {
                if (visNode[v]) continue;
                visNode[v] = true;
                int len = adj[v].size();
                
                rep(i,0,len) {
                    node next = adj[v][i];
                    int next_color = next.color;
                    if (vis[next_color] || visNode[next.to]) continue;
                    
                    dis[next_color] = dis[now]+1;
                    Q.push(next_color);
                    vis[next_color] = true;
                }
            }
        }
        
        int ans = INT_MAX;
        rep(i,0,adj[commonB].size()) {
            node edge =adj[commonB][i];
            int des_color = edge.color;
            ans = min(ans, dis[des_color]);
        }
        
        cout<<ans<<endl;
        
        
    }
    
    return 0;
}

官方题解则是通过加边的方法传送门
请添加图片描述将染色边转化为一个新的染色节点连接到原有边的端点。可能这样画体现不出这个方法精妙之处。请添加图片描述点多了就能看出来,这样形成一个星形的连接,相同颜色的点之间移动都只需要经过两条边。仍然还是bfs,只不过由于边多加了,所以需要最终结果/2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/577497.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

发那科FANUC机器人R-2000iB平衡缸维修攻略

在发那科机器人中&#xff0c;平衡缸扮演着稳定机械臂运动的关键角色。它通过内部的压力调节来平衡负载&#xff0c;保证机器人的精准定位和平稳操作。一旦出现法兰克机械手平衡缸故障或损坏&#xff0c;机器人的性能可能会大打折扣&#xff0c;因此及时且正确的FANUC机械手平衡…

uniapp获取当前位置及检测授权状态

uniapp获取当前位置及检测授权定位权限 文章目录 uniapp获取当前位置及检测授权定位权限效果图创建js文件permission.jslocation.js 使用 效果图 Android设备 点击 “设置”&#xff0c;跳转应用信息&#xff0c;打开“权限即可”&#xff1b; 创建js文件 permission.js 新建…

HTTP基础知识

1. HTTP常见的状态码有哪些&#xff1f; 常见状态码&#xff1a; 200&#xff1a;服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。 301 &#xff1a; (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时&a…

Java使用SpringBoot和EasyExcel 实现动态数据导出实战

Java使用SpringBoot和EasyExcel 实现动态数据导出实战 1、前言2、【资源地址】3、代码示例(demo)4、目前Java实现数据导出为Excel方式5、依赖6、总结 1、前言 工作中有用到将数据导出为Excel的场景&#xff0c;在此记录下。在日常开发中&#xff0c;Excel文件处理是一项常见的…

LeetCode 面试题 08.02——迷路的机器人

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 此题就是一个典型的图搜索题&#xff0c;一种就是广度优先搜索&#xff0c;一种就是深度优先搜索。 3. 代码实现 class Solution { public:vector<vector<int>> pathWithObstacles(vector<vecto…

软件需求管理规程(Word原件2024)

软件开发人员及用户往往容易忽略信息沟通&#xff0c;这导致软件开发出来后不能很好地满足用户的需要&#xff0c;从而造成返工。而返工不仅在技术上给开发人员带来巨大的麻烦&#xff0c;造成人力、物力的浪费&#xff0c;而且软件的性能也深受影响。所以在软件项目开发周期的…

Bellman Ford算法:解决负权边图的最短路径问题

Bellman Ford算法的介绍 在计算机科学的世界中&#xff0c;Bellman Ford算法是一种解决单源最短路径问题的算法&#xff0c;它可以处理有负权边的图。这个算法的名字来源于两位科学家Richard Bellman和Lester Randolph Ford&#xff0c;他们是这个算法的发明者。 这个算法的主…

hive启动beeline报错

问题一在zpark启动集群报错 出现上面的问题执行以下代码 chmod 777 /opt/apps/hadoop-3.2.1/logs 问题二启动beeline报错 执行 cd /opt/apps/hadoop-3.2.1 bin/hadoop dfsadmin -safemode leave 问题三执行查询语句报错 执行 set hive.exec.mode.local.autotrue;

公考相丽君政治素养研习课

公考相丽君政治素养研习课&#xff0c;是广大公考学子提升政治素养、深化政治理解的宝贵课程。相丽君老师以其深厚的政治理论功底和丰富的教学经验&#xff0c;为学员们呈现了一堂生动而深刻的政治课。课程中&#xff0c;相老师深入浅出地讲解了政治理论的基本概念和核心思想&a…

Windows系统下将MySQL数据库表内的数据全量导入Elasticsearch

目录 下载安装Logstash 配置Logstash配置文件 运行配置文件 查看导入结果 使用Logstash将sql数据导入Elasticsearch 下载安装Logstash 官网地址 选择Windows系统&#xff0c;需下载与安装的Elasticsearch相同版本的&#xff0c;下载完成后解压安装包。 配置Logstash配…

ChuanhuChatGPT集成百川大模型

搭建步骤&#xff1a; 拷贝本地模型&#xff0c;把下载好的Baichuan2-7B-Chat拷贝到models目录下 修改modules\models\base_model.py文件&#xff0c;class ModelType增加Baichuan Baichuan 16 elif "baichuan" in model_name_lower: model_type ModelType.Ba…

(超全)python图像处理详细解析(3)

图像处理 23.保存视频每一帧图像24.把png图像转换成jpg并保存25.改变图像尺寸26.改变图像比例27.旋转图像28.亮度调整29.log对数调整30.判断图像对比度31.调整强度&#xff08;1&#xff09;强度调节&#xff08;2&#xff09;uint8转float 32.绘制直方图和均衡化33.彩色图片三…

基于streamlit快速部署机器学习项目(Public URL)

基于streamlit的AIGC项目前端展示 1.Streamlit 简介与入门1.1 安装 Streamlit1.2 开发Streamlit应用程序1.3 启动并运行1.3.1 本地运行1.3.2 部署 现在LLM技术发展迅速&#xff0c;很多人在学习的时候&#xff0c;都想展示效果&#xff0c;并且想部署在服务器上&#xff0c;但是…

原型链prototype、__proto、constructor的那些问题整理

再了解原型链之前,我们先来看看构造函数和实例对象的打印结构 - 函数 这里我们定义一个构造函数Fn,然后打印它的结构吧 function Fn(){} console.dir(Fn)控制台得到结构 从上面结构我们能看的出来,函数有两种原型,一种是作为函数特有的原型:prototype,另一种是作为对象的__…

数字旅游:通过科技赋能,创新旅游服务模式,提供智能化、个性化的旅游服务,满足游客多元化、个性化的旅游需求

目录 一、数字旅游的概念与内涵 二、科技赋能数字旅游的创新实践 1、大数据技术的应用 2、人工智能技术的应用 3、物联网技术的应用 4、云计算技术的应用 三、智能化、个性化旅游服务的实现路径 1、提升旅游服务的智能化水平 2、实现旅游服务的个性化定制 四、数字旅…

计算机网络大框架图形

如标题&#xff0c;精心画了一个计算机网络的框架性的图&#xff0c;包含了计算机网络的核心思想&#xff0c;在此分享和备份下。各层具体协议参考TCP/IP常用协议栈图解-CSDN博客

工厂数字化三部曲/业务、数据和IT融合

工厂数字化三部曲: 业务、数据和IT融合 在当今数字化转型的潮流中&#xff0c;企业面临着将业务、数据和IT融合的挑战和机遇。数字化转型不仅是技术上的升级&#xff0c;更是对企业运营模式和管理体系的全面优化和重构。通过业务“数字化”阶段的细致分析和整合&#xff0c;以及…

葡萄牙语翻译中文难吗,葡译中如何翻译比较好?

葡萄牙&#xff0c;一个充满魅力的国度&#xff0c;拥有着悠久的历史和丰富的文化传统。葡萄牙语作为这个国家的官方语言&#xff0c;在全球范围内享有广泛的声誉。那么&#xff0c;葡萄牙语翻译中文难吗&#xff1f;又该如何进行高质量的翻译呢&#xff1f; 业内人士指出&…

蛋糕购物商城

蛋糕购物商城 运行前附加数据库.mdf&#xff08;或使用sql生成数据库&#xff09; 登陆账号&#xff1a;admin 密码&#xff1a;123456 修改专辑价格时去掉&#xffe5;以及上传专辑图片 c#_asp.net 蛋糕购物商城 网上商城 三层架构 在线购物网站&#xff0c;电子商务系统 …

打造智能语音机器人-用语音控制机器人

人工智能现已成为国家发展重大战略&#xff0c;智能语音技术作为人工智能产业链上的关键一环&#xff0c;AI应用成熟的技术之一&#xff0c;人工智能的发展也进入了一个崭新的阶段。那么打造智能语音机器人怎样实现用语音控制机器人呢&#xff1f;和小编一起来看看。 选择合适的…