代码编织梦想

蓝桥杯之二分

但是左端点的更新也要自己找规律,扫地机器人是根据当前遍历到的机器人的位置和左端点L的位置的前后不同更新L,区间移位是根据L和当前遍历到的区间最大能移到L的左边还是右边,以及区间右端点来看的。

区间移位

在这里插入图片描述
图片来自

  • 举例区间a【1 ~ 10】,b【2 ~ 4】 或 a1【1000,2000】,b1【1200,1300】
    对于左端点极小右端点极大的长度很大的区间a,应该合理加以利用,移动到右侧最近的位置,防止左端点更大右端点更小的区间b,因为不合理的移动(如果按左端点排序,b区间后于a区间移动,b区间移动某种程度上需要跨过a区间的长度距离,到达a的右端点才能找到未被覆盖的点再进行拼接)而导致的移动位移增大,不管用哪种贪心方法永远是要找到最左的未被覆盖的点进行拼接,
    按右端点排序,避免因区间程度造成的位移增多(长度短的区间需要徒劳移出长度长的区间再去补空白区间)

  • 分析样例可以知道,答案可能存在0.5,1.5,2.5等。那么我们将所有数值扩大两倍,最后再除2就可以了。

1、需要多次遍历区间

3、二分判断是否可行,每次判断都需要对edge和vis数组初始化
4、vis数组来防止区间重复利用,如果用vector数组也可以tmp.erase(tmp.begin()+i) (注意括号里面是迭代器)

2、每找到一个可行区间,结束循环???突然发现用vis数组标记的方式不需要每找到一个可行区间就break,但是用vector数组erase的方式,如果不break就只能过30%,好了,都是erase之后指针错乱,代码解释
每删除一个元素就i-- 让指针回溯一个位置,因为此时被删除元素的后一个元素 对应的下标就是此时的i

	vector<int> v;
	v.clear();
	v.push_back(0);
	v.push_back(1);v.push_back(2);
	v.push_back(3);v.push_back(4);
	v.push_back(5);v.push_back(6);
	for(int i=0;i<v.size();i++){
		cout<<v[i]<" ";
		if(v[i]&1){
		v.erase(v.begin()+i);
		i--;
	}	
#include<bits/stdc++.h>
#include<algorithm>
#include<iomanip>
using namespace std;
const int N=1e4+5;
typedef struct node{
	int l,r;
	bool operator<(const node & p)const{
		return r<p.r;
	}
}node;
int n,x,y;
node a[N];
int vis[N];
bool adequate(int x){//位移差最大的那个区间的位移量为x
int edge=0;
memset(vis,0,sizeof(vis));
while(true){
	bool flag=false;
	
	for(int i=0;i<n;i++){
		int sl=a[i].l,sr=a[i].r;
		if(!vis[i]&&sl-x<=edge&&sr+x>=edge){//移动区间可能 覆盖第一个未被覆盖的点
			int len=sr-sl;
//		覆盖之后,edge(被覆盖的右端点)能延伸到哪儿呢 edge+len or sr+x
//		不一定要移动x这么远,如果sl+x>=edge(移动之后 sl会超出edge)
//		注意这里有两种情况,sl>x 或者sl<x,前者向左移,后者向右移动
			if(sl+x>=edge)edge+=len;
			else edge=sr+x;
			vis[i]=1;
			flag=true;
			if(edge>=20000)return true;
			break;
		}
	}
	if(!flag&&edge<20000)return false;
}
//if(edge>=20000)return true;或者这一句写在这里
}
signed main(){//8:32  位移差最大的那个区间的位移量最小
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>x>>y;
		a[i].l=x*2;
		a[i].r=y*2;
		
	}
	sort(a,a+n);
	int l=0,r=1e4*2;
	while(l<r){
		int mid=l+r>>1;
		if(adequate(mid))r=mid;
		else l=mid+1;
	}
	cout<<l/2.0;
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n, a, b;
struct node
{
    int a, b;
};
vector<node> q;
bool cmp(node x, node y)
{
    return x.b < y.b;
}
bool check(int m)   //最大移动距离m,判断是否能覆盖整个区间; 
{
    vector<node> tmp(q);   //建立一个q的复制tmp; 
    int k = 0;   //最大能覆盖的区间右端点; 
    while(true)
    {
        bool flag = false;
        for(int i = 0; i < tmp.size(); i++)
        {
            node now = tmp[i];
            int ta = now.a;
            int tb = now.b;
            if(ta-m <= k && tb+m >= k) //k在区间[ta-x, tb+x]内,不在则m太小; 
            {
                flag = true;
                int len = tb - ta; //当前这个区间的长度; 
                if(ta+m >= k)     
                    k = k + len; //k最大能多覆盖到k+len的范围; 
                //ta+x>=k,那么只需要让区间的左端点移动到k处,右端点此时在k+len处;
                else
                    k = tb + m;  //ta+x<k,k最大能多覆盖到该区间的右端点,再多走m的长度;
                tmp.erase(tmp.begin()+i);  //将选择的区间去掉,避免重复判断; 
                // break; i--使得指针i不受erase的影响继续指向下一些个元素
                i--;
                if(k >= 20000)return true;
               
            }
        }
        if(k >= 20000 || !flag) break; 
        //如果找不到可以覆盖的区间,或者k已经达到20000了,就可以结束检验了;
    }
    return false;
}
int main()
{    
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        cin >> a >> b; 
        a *= 2;      //答案存在0.5,可以将所有东西扩大两倍,最后再除2就可以了; 
        b *= 2;
        q.push_back({a, b});
    }
    sort(q.begin(), q.end(), cmp); //按右端点从大到小排序; 
    int l = 0, r = 20000;  //因为扩大了2倍,枚举答案范围也大了2倍; 
    while(l < r)  //二分答案:枚举最大移动的距离,使最大移动距离最小; 
    {
        int mid = (l+r)/2;
        if(check(mid))
            r = mid ;
        else 
            l = mid + 1;        
    }
    double ans = (l) / 2.0;
    cout << ans << endl;
    return 0;
}

扫地机器人

解题思路:不用遍历所有机器人的运动轨迹,只需要求出单个机器人花的最大时间
即可完成本题,利用二分查找查找最大时间
步骤:
1.利用二分查找每次分两个区域
2.定义检查函数检查是否扫完
3.在函数体内遍历每个机器人一次性扫多少个地,这个地我们用x表示,求出最小x即可
在定义一个s代表扫了多少个地,遍历完在判断s是否>=n即可,
由于每个机器人扫的地都一样,所以最后的结果一定会>=n
4.那个最小的x就是我们的最终结果

假设某个机器人需要清扫 a,b,c,d 四个格子,因为这个机器人清扫完还需要回到最初始的位置,所以无论这个机器人初始位置在什么地方,
其清扫路径的本质都是重复两次 a 到 b,b 到 c,c 到 d 的过程,花费时间为 6,由此,假设某个机器人清扫的格子范围为 l,
那么这个机器人花费的时间为 ( l − 1 ) × ∗ 2 (l-1)\times*2 (l1)×2。所以只需要对机器人清扫的范围(l)进行二分即可,最后的答案为 t = ( l − 1 ) × ∗ 2 t=(l-1)\times*2 t=(l1)×2
显然当每个机器人清扫的范围大小相同时,花费时间最小。
可以对清扫范围进行二分,然后验证其答案的正确性即可,判断条件是清扫范围可以使得每个格子都能够扫到

可以明显的知道,最左边的格子由左边第一台机器人清扫,花费时间是最少的,在此可以采用贪心的思想,
让每台机器人都要优先清扫其左边还未扫的到格子,然后再往右扫,在二分得到的范围下往右扫得越多越好,
这样可以减少右边下一个机器人需要往左扫的范围,增加其往右扫的范围,以此类推,可减少清扫时间。

综上,本题采用二分加贪心的思想解答。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,k;
int a[N];
bool adequate(int x){//假设每个机器人能扫过x个点
	int edge=0;
	for(int i=0;i<k;i++){
		if(a[i]-x>edge)return false;
		if(a[i]<edge)edge=a[i]+x-1;// 2 3 4  假设a[i]为2,x=3,则可以扫到2 3 4
		else edge=a[i]+x-1-(a[i]-edge-1);//机器人a[i]往左走 走到扫到edge,这样一来
//	十分注意x是能扫过的点,暂时不要考虑路程,原先edge在a[i]左边,a[i]左右扫x个点
//	于是edge`=edge+x
	}
	return edge>=n;
}
signed main(){
	cin>>n>>k;
	for(int i=0;i<k;i++){
		cin>>a[i];
	}
	sort(a,a+k);
	int l=0,r=n;//机器人打扫的范围,路程为 (范围-1)*2
//	注意了这里的打扫范围指的是机器人能经过的所有点,
//	n个方格区域假设只有1个机器人,那么该机器人的打扫范围就是n,实际上路程为(n-1)*2
	while(l<r){ 
		int mid=l+r>>1;
		if(adequate(mid)){
			r=mid;
		}
		else l=mid+1;
		
	}
	cout<<(l-1)*2;
	return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_51070956/article/details/129472025

蓝桥杯C/C++组 经验分享-爱代码爱编程

蓝桥杯C/C++组 经验分享 2020.2.7 , CJ ,芯科经验分享讲稿 参考博客 蓝桥杯软件比赛中的注意事项(C/C++) C/C++组 B组推荐原因 电院一直以来蓝桥杯硬件类硕果累累,但是软件类很少人参加,因为盛传C/C++组竞争激烈,但是实际上C/C++组获奖人数多, 且大一新生还未开模电数电等课程,只学了c语言,正好准备蓝

蓝桥杯常用代码模板总结(C/C++)-爱代码爱编程

蓝桥杯常用代码模板总结(C/C++) 1.排序 (1)冒泡排序 C++代码: void BubbleSort(int a[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++)

2021蓝桥杯省赛B组(C++)题解-爱代码爱编程

A:卡片 题目描述 小蓝有很多数字卡片,每张卡片上都是数字0 到9。 小蓝准备用这些卡片来拼一些数,他想从1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。 小蓝想知道自己能从1 拼到多少。 例如,当小蓝有30 张卡片,其中0 到9 各3 张,则小蓝可以拼出1 到10,但是拼11 时卡片1 已经只有一张了,不够拼出11。 现在小蓝手里

C++蓝桥杯基础知识常用整理-爱代码爱编程

不是很详细哦 但是绝对好记切实用 目录 1.整型 2.浮点型 3.运算符  4.取int的最大值 5.输出格式 6.常用math函数  7.数组定义需知 1.整型         对整型来说,如果绝对值在10的九次方范围内,都可以定义为int型         一个int占32bit,也就是4字节(可能第一题会

2021年蓝桥杯省赛 C++ B组-爱代码爱编程

目录  1550: [蓝桥杯2021初赛] 卡片  1551: [蓝桥杯2021初赛] 直线  1552: [蓝桥杯2021初赛] 货物摆放 1553: [蓝桥杯2021初赛] 路径  1555: [蓝桥杯2021初赛] 空间 1563: [蓝桥杯2021初赛] 时间显示  1550: [蓝桥杯2021初赛] 卡片 题目描述 小蓝

2021蓝桥杯C/C++B组真题-爱代码爱编程

1.空间 小蓝准备用256MB的内存空间开一个数组,数组的每个元素都是32 位二进制整数。如果不考虑程序占用的空间和维护内存需要的辅助空间,请问256MB 的空间可以存储多少个32 位二进制整数? 256x1024x1024x8/32=67108864 2.卡片 小蓝有很多数字卡片,每张卡片上都是数字0到9。 小蓝准备用这些卡片来拼一些数,他想从1

蓝桥杯——2021第十二届C/C++真题[省赛][B组]-爱代码爱编程

目录 卡片 直线 货物摆放 路径 空间 砝码称重 时间显示  杨辉三角数   双向排序 括号序列  卡片 思路:这道题咋一看给人一种挺难的感觉,其实很简单,就是一个数的每位遍历。 #include<iostream> using namespace std; int main() { int a[10] =

【2022第十三届蓝桥杯】c/c++ 大学c组 解题报告-爱代码爱编程

 大家好,我是小单同学,欢迎交流指正~    今天上午蓝桥杯圆满落幕,准备了几个月的比赛也终于打完了。今年填空题变成了两道,同学们反映今年难度上升很大,小单也感觉今年难度较大hh,空了两道题。现在给大家分享一下本菜鸡的解题报告,供大家交流。仅供参考哈。 目录  ​大家好,我是小单同学,欢迎交流指正~ ​ 🎁试题 A: 排列字母 🍞代码详解

2022年蓝桥杯省赛真题解析(C++B组)-爱代码爱编程

        2022.04.09,我第一次参加蓝桥杯,我想说今年官方为了防止作弊,可谓煞费苦心,直接启用备用卷,难度直接到国赛难度。第一次参加,却让我输的那么彻底。 目录 A九进制转十进制​ B 顺子日期 C 刷题统计 D 修剪灌木 E X进制减法 F 统计子矩阵 G 积木画  H 扫雷 I 李白打酒加强版 J 砍竹子 A九

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解-爱代码爱编程

========================================== 2019-2021蓝桥杯C++ B组真题题解:2019第十届蓝桥杯大赛软件类省赛C++ B组真题题解2020第十一届蓝桥杯大赛软件类省赛第二场C++ B组真题题解2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解 =========================

2022年第十三届蓝桥杯大赛C组真题C/C++解析(上)-爱代码爱编程

**今天给大家带来2022年,第十三届蓝桥杯大赛的真题解析** 转眼间,距离考试已经过去很长时间了,今天解元给大家解析一下,有问题欢迎大家指点 :笑: 下面进入正题 前言填空题1.排列字母2.特殊时间编程题1.纸张尺寸1.1纸张大小代码2.求和2.1求和代码3.数位排序3.1数位排序代码结语 前言 考试已经结束,有的

2022年蓝桥杯省赛 C/C++ A组题解-爱代码爱编程

前言: NewOJ最新推出2022蓝桥杯省赛题目,数据均为管理员自行构造,仅供参考。 传送门:http://oj.ecustacm.cn/viewnews.php?id=1021。 题目总览 题目Tag难度补题链接裁纸刀模拟☆http://oj.ecustacm.cn/problem.php?id=2021灭鼠先锋博弈☆☆☆http://oj.ecu

2022年6月第十三届蓝桥杯大赛软件赛全国决赛c++a组题解_hesorchen的博客-爱代码爱编程

目录 试题 A: 小蓝与钥匙试题 B: 排列距离试题 C: 内存空间试题 D: 最大公约数试题 E: owo试题 F: 环境治理试题 G: 选素数试题 H: 替换字符试题 I: 三角序列试题 J: 括号序列树 试题 A: 小蓝与钥匙 C(28,14)*错排 试题 B: 排列距离 康托展开 试题 C: 内存空间 预计得分:1

第十三届蓝桥杯c++b组2022年国赛决赛题解_int 我的博客-爱代码爱编程

题目pdf下载:十三届蓝桥杯c++b组2022国赛题目pdf下载 G题没有写,J题是暴力的,其他好像都写出来,但是估计还是有错的。 目录 正文: 试题 A: 2022 试题 B: 钟表 试题 C: 卡牌 试题 D: 最大数字 试题 E: 出差 试题 F: 费用报销 试题 G: 故障 试题 H: 机房 试题 I: 齿轮 试题 J:

2022年十三届蓝桥杯国赛(c/c++大学b组)个人题解_polarday.的博客-爱代码爱编程

2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解 去年国赛基本都是暴力,最后国三都没拿到(我是废物 ),今年感觉比去年难了不少,而且时间没有安排好,第一题就被卡了好久,然后G题概率论也分析了好久,导致最后三题都没时间做了,总之就是一点暴力分都没骗到,希望做的题能多对几道吧,希望能拿个国三。 试题 A: 2022 【问题描述】 将 202

蓝桥杯2022年(本科c++b组)_物联网土猫的博客-爱代码爱编程

目录 一:刷题统计 二:修剪灌木 三:X进制减法 四:统计子矩阵 五:积木画 六:扫雷 七:李白打酒加强版 八:砍竹子 一:刷题统计  题目链接:4402. 刷题统计 - AcWing题库 因为本人补题都是在acwing上面,所以所有题目链接都会是acwing,大家也可以在c语言网上提交,题目数据都是相同的,都可以提交,额,y总

二分查找例题(三)蓝桥杯 分巧克力-爱代码爱编程

题目描述(截屏来自洛谷 P8647): #include <iostream> using namespace std; int a[200005]; int main() { int n, k; cin >> n >> k; for (int i = 0; i < 2 * n; i+

【蓝桥杯】第十三届蓝桥杯省赛 ak 攻略 —— c++ b组全真题超详细剖析_蓝桥杯第十三届省赛-爱代码爱编程

🎄目录 🌼写在前面🌻 A题 --- 九进制转十进制🌷 题目描述🌷 解题思路🌷 代码编写 🌻 B题 --- 顺子日期🌷 题目描述🌷 解题思路🌷 代码编写 🌻 C题 --- 刷题统计🌷 题目描述🌷

2022年第十三届蓝桥杯省赛c++b组【真题解析】_2022蓝桥杯b组真题-爱代码爱编程

目录            第一题:九进制转十进制            第二题:顺子日期            第三题:刷题统计            第四题:修剪灌木            第五题:X进制减法            第六题:统计子矩阵            第七题:积木画            第八题:扫雷      

备战蓝桥杯——c++基础算法(一)_蓝桥杯c++-爱代码爱编程

Hello,大家好!我是阿冰!在我的上一个“不忘初心”的博客中提到,过一周左右我要参加学校组织的程序设计大赛,以及要准备蓝桥杯,我们学校的比赛题型也是参考蓝桥杯的题型,不管怎样,最重要的都是蓝桥杯,校赛也一直抱着学习总结的心