第一章 基础算法(三)

文章目录

  • 双指针算法
    • 双指针算法分类
      • 双指针算法模板
      • 性质:
      • 总结
      • 例1
      • 例2
  • 位运算
    • 二进制的第k位
    • lowbit 返回x的最后一位1
      • 实现
      • 计算机中编码知识
      • 做题思路
  • 离散化
  • 区间合并

双指针算法

双指针算法分类

image-20220731112247867

双指针算法模板

image-20220731112316354

性质:

image-20220731112608699

总结

image-20220731113656500

为什么双指针算法可以起到优化的作用:

i:0->n

j:0->n 在每次循环完毕,j不需要归零,因此j也是0->n

两个指针最多为2n

例1

输入字符串,把其中每一个单词输出来,单词之间用空格隔开
#include <iostream>
#include <cstring>using namespace std;int main()
{char str[1000];gets(str);int n = strlen(str);for(int i = 0;str[i];i++){int j = i;//分清楚while(j < n && str[j] != ' ') j++;//这道题的具体逻辑for(int k = i;k < j;k++) printf("%c",str[k]);printf("\n");i = j;}return 0;
}

例2

双指针怎么想:可以从暴力的方式想,然后利用单调性改进

给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。输入格式
第一行包含整数 n。第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。数据范围
1≤n≤105
输入样例:
5
1 2 2 3 5
输出样例:
3

image-20220731115647238

s[N]

s[a[i]]]++

//799
#include <iostream>using namespace std;const int N = 100010;
int a[N];
int s[N];  //计数器,每个数出现的次数
int n;
int main()
{cin>>n;for(int i = 0;i < n;i++ ) cin >> a[i];int res = 0;for(int i = 0,j=0 ;i < n;i++){s[a[i]]++;while(s[a[i]] > 1){s[a[j]]--;  //j表示弹出数据,对应统计的数量降低j++;  //向前移动}res = max(res,i-j+1);  //因为最后一次可能不是最大的,该值用于统计累加过程中整个串中最大的一次数值记录}cout<< res <<endl;return 0;
}

位运算

二进制的第k位

image-20220731143615984

//n的二进制表示中第k位
#include <iostream>
#include <cstring>using namespace std;
int main()
{int n = 10;for(int k = 3;k>=0;k--)//向右移动k位cout<< (n>>k&1);return 0;
}

lowbit 返回x的最后一位1

给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。输入格式
第一行包含整数 n。第二行包含 n 个整数,表示整个数列。输出格式
共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1 的个数。数据范围
1≤n≤100000,
0≤数列中元素的值≤109
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2

image-20220731144251751

实现

lowbit的实现:x & -x

~代表数值取反

image-20220731144352526

image-20220731144552552

应用:统计x中1的个数。

要先学会走路,再学会飞。不能还不会走路,就去飞。一步步来,不然会摔得很惨

#include <iostream>using namespace std;int n;int lowbit(int x)
{return x & -x;
}
int main()
{cin>>n;//针对每一个数值进行处理,不需要存储相关信息while(n--){int x;cin>>x;int res = 0;while(x) x -= lowbit(x),res++;  //每次减去x的最后一位cout<<res<<' ';}return 0;}

计算机中编码知识

image-20220731145447925

解释为什么反码是取反后加一,而不是直接取反?

计算机底层实现没有减法,减法由加法实现

image-20220731145703454

做题思路

人类做题的过程就是dfs的过程

image-20220731150124215

有同学学习比较快,或者接触比较早,或者对各种算法已经熟悉了


离散化

假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。输入格式
第一行包含两个整数 n 和 m。接下来 n 行,每行包含两个整数 x 和 c。再接下来 m 行,每行包含两个整数 l 和 r。输出格式
共 m 行,每行输出一个询问中所求的区间内数字和。数据范围
−109≤x≤109,
1≤n,m≤105,
−109≤l≤r≤109,
−10000≤c≤10000
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5

特指整数离散化,保序离散化

image-20220731150745064

image-20220731151018801

image-20220731152706736

image-20220731152921632

image-20220731160546759

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;typedef pair<int,int> PII;const int N = 300010;
int n,m;
int a[N],s[N];vector<int> alls;vector<PII> add,query;int find(int x)
{int l = 0,r = alls.size()-1;while(l < r){int mid = l + r >>1;if(alls[mid] >= x) r = mid;else l = mid + 1;}return r+1;
}//java/python中无unique函数,如何用代码实现
/*
vector<int >::iterator unique(vector<int > &a)
{int j = 0;for(int i = 0 ; i < a.size();i++)if(!i || a[i] != a[i-1])a[j++] = a[i];//a[0]~a[j-1] 所有a中不重复的数return a.begin() + j;
}
*/int main()
{cin>>n>>m;for(int i = 0;i<n;i++){int x,c;cin>>x>>c;add.push_back({x,c});alls.push_back(x);}for(int i = 0;i<m;i++){int l,r;cin>>l>>r;query.push_back({l,r});alls.push_back(l);alls.push_back(r);}//去重sort(alls.begin(),alls.end());// 使用C++库中unique函数alls.erase(unique(alls.begin(),alls.end()),alls.end());//手写后unique函数//alls.erase(unique(alls),alls.end());//处理插入for(auto item : add){int x = find(item.first);a[x] += item.second;}//预处理前缀和for(int i = 1;i <= alls.size();i++) s[i] = s[i-1] + a[i];//处理询问for(auto item : query){int l = find(item.first), r =find(item.second);cout<< s[r] -s[l-1]<<endl;}return 0;
}

区间合并

给定 n 个区间 [li,ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。输出合并完成后的区间个数。例如:[1,3][2,6] 可以合并为一个区间 [1,6]。输入格式
第一行包含整数 n。接下来 n 行,每行包含两个整数 l 和 r。输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。数据范围
1≤n≤100000,109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3

image-20220731161749941

image-20220731161852144

image-20220731162404742

image-20220731162615600

区间合并的思路如下:

  1. 确定一个标准区间
  2. 从候选区间中拿出一个比较,可以分为两种情况
    1. 起始区间在标准区间中
    2. 起始区间在标准区间外
  3. 将最后的区间加入至结果中

image-20220806085821768

//Acw版本
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;
const int N = 100010;typedef pair<int,int > PII;int n;
vector<PII> segs;void merge(vector<PII> &segs)
{vector<PII> res;  //用于存储合并结果sort(segs.begin(),segs.end());  //字典序排序,从first元素开始排序int st =  -2e9,ed = -2e9;  //一开始虚构的标准区间,只初始化一次,不能添加至结果中for(auto seg:segs){if(seg.first > ed)//if(ed < seg.first){if(ed != -2e9) res.push_back({st,ed});  //将区间放置于结果区间中,不能将一开始虚构的区间至于结果中st = seg.first,ed = seg.second;  //区间进行赋值}else ed = max(ed,seg.second);}if(st != -2e9) res.push_back({st,ed}); //同上segs = res;
}int main()
{cin>>n;for(int i = 0;i < n;i++){int l,r;cin>>l>>r;segs.push_back({l,r});}merge(segs);cout<<segs.size()<<endl;return 0;
}

自我理解版:

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;typedef pair<int,int > PII;
vector<PII> segs;
int n,l,r;void merge(vector<PII> &segs)
{vector<PII> res;int st = -2e9;int ed  = st;sort(segs.begin(),segs.end());for(auto seg:segs){if(seg.first > ed){if(ed != -2e9 ) res.push_back({st,ed});  //不能将一开始虚构的区间至于结果中st = seg.first, ed = seg.second;}elseed = max(seg.second,ed);}if(ed != -2e9 ) res.push_back({st,ed});  //同上segs = res;
}
int main()
{scanf("%d",&n);while(n--){scanf("%d%d",&l,&r);segs.push_back({l,r});}merge(segs);printf("%ld",segs.size());return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二章 数据结构(二)

文章目录Trie树存储并查集常规例题并查集维护多余信息堆性质存储基础操作downup操作例题Trie树 Tire&#xff1a;高效地存储和查找字符串集合的数据结构 存储 如果没有就创建。 对单词结尾进行标记&#xff0c;表示以当前节点结尾的地方存在一个单词 维护一个字符串集合&am…

Apache Camel 3只有2个月的路程

骆驼队正忙于为 Apache Camel3 。今天&#xff0c;第二个候选版本已构建并发布在暂存库中&#xff0c;供早期的适配器尝试 。 当我自己很忙的时候&#xff0c;我只想写一篇简短的博客文章&#xff0c;以使社区了解Apache Camel 3即将发布&#xff0c;我们希望它在今年年底&am…

第二章 数据结构(三)

文章目录哈希表存储结构拉链法&#xff1a;插入查询题目注意开放寻址法查找质数代码字符串哈希方式STL相关知识哈希表存储结构 整体结构 0~109->0~105 方法&#xff1a; x mod 105处理冲突 开放寻址法拉链法 拉链法&#xff1a; 思想&#xff1a;每个槽上拉一条链&…

Vaadin 10+作为CUBA UI的未来

从一开始&#xff0c;Vaadin就成为CUBA平台用户界面的基石和重要组成部分。 由于其创新的方法&#xff0c;它帮助CUBA将企业用户界面开发带到了一个非常有希望的&#xff08;如今是默认&#xff09;的WEB领域。 Vaadin最令人兴奋的部分之一是整个开发都是同构的&#xff0c;并且…

第二章 数据结构(一)

文章目录整体结构为什么用数组链表与邻接表单链表存储插入插入至头结点将x插入到下标为k的点后面删除遍历双链表初始化插入删除邻接表栈和队列栈队列单调栈单调队列KMP整体结构 链表与邻接表&#xff08;用数组模拟&#xff09;栈与队列&#xff08;用数组模拟&#xff09;kmp…

第三章搜索与图论(一)

文章目录DFS与BFS区别DFS全排列n皇后BFS树和图的遍历树和图的存储数和图的遍历深度优先遍历宽度优先遍历图的宽搜应用框架DFS与BFS区别 DFS: 执着&#xff1a;一直走到头&#xff0c;回去的时候边回去边看能不能向下走 BFS: 稳重&#xff1a;每次只扩展一层&#xff0c;不会…

第三章 搜索与图论(二)

文章目录最短路朴素Dijkstra算法堆优化版的Dijkstra算法Bellman-Ford算法SPFA算法求距离判负环Floyd最短路 并不区分有向图和无向图&#xff0c;因为无向图是一种特殊的有向图。直接用有向图的算法&#xff0c;解决无向图的问题。 常见情况可以分为两大类 在图论中&#xff0…

第三章 搜索与图论(三)

文章目录朴素版PrimKruskal算法染色法匈牙利算法朴素版Prim 给定一个 n 个点 m 条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出 impossible。给定一张边带权的无向图 G(V,E)&a…

CDF 图的含义

CDF 图用于创建经验累积分布函数图。 使用 CDF 图可以确定等于或小于 x 轴上的给定值的数据的百分比。 例如&#xff0c;在该 CDF 图中&#xff0c;大约 34% 的数据小于总脂肪值 10 克。 参考链接 1. https://www.jmp.com/support/help/zh/14-2/ba-distribution-22.shtml

rome rss_RSS阅读器使用:ROME,Spring MVC,嵌入式Jetty

rome rss在这篇文章中&#xff0c;我将展示一些创建Spring Web应用程序的指南&#xff0c;这些应用程序使用Jetty并使用名为ROME的外部库运行RSS来运行它。 一般 我最近创建了一个示例Web应用程序&#xff0c;充当RSS阅读器。 我想检查ROME以阅读RSS。 我还想使用Spring容器和…

Ubuntu系统输入中文方式

我目前知道Ubuntu有两个还算好用的中文输入法&#xff1a; Fcitx&#xff1a;它是Linux世界开源的输入法框架&#xff0c;提供 Google PinYin、ShuangPin、SunPinYin、Wubi、ZhengMa、Hong Kong 和 TaiWan繁体等输入法。 1 安装Fcitx sudo apt install fcitx-pinyin fcit…

VMWare建立于W10的共享文件夹

一、共享文件夹建立 在虚拟机设置 -> 文件夹共享&#xff0c;选择总是启用&#xff0c;点击添加&#xff1a; 直接点击下一步&#xff1a; 选择原系统共享文件夹位置&#xff0c;并命名&#xff1a; 选择启用此共享&#xff0c;并继续&#xff1a; 二、VMtools安装 虚拟机…

VSCode如何去掉Monokai主题下的绿色下划线

VScode中类似sublime的主题为Monokai&#xff0c;但是自带主题Monokai中绿色下划线令人不舒服。 在网上寻找多种方式去除下划线。终于找到一种合适的处理方式。 1 安装主题插件 在主题插件中搜索One Monokai Theme&#xff0c;下载并安装 2 配置全局主题 通过快捷键“Ctr…

解决 ZLibrary 登录/注册不了的问题

一 文章转载链接内容 转载链接&#xff1a;解决 ZLibrary 登录/注册不了的问题 - 知乎 很多小伙伴反馈说 Z-Library 能打开&#xff0c;但是不能登录。这实际上是由于官方登录入口受限导致的。话虽如此&#xff0c;我们仍然可以通过某些方法绕过这个限制。 >虽然我们注册时…

gradle入门_Gradle入门:简介

gradle入门Gradle是一种构建工具&#xff0c;可以用基于Groovy编程语言的内部DSL替换基于XML的构建脚本。 最近它吸引了很多关注&#xff0c;这就是为什么我决定仔细研究一下。 这篇博客文章是我的Gradle教程的第一部分&#xff0c;它有两个目标&#xff1a; 帮助我们安装Gr…

排队论游乐场的游乐项目_外汇游乐场

排队论游乐场的游乐项目介绍 F X Playground是基于JavaFX的原型制作工具或实时编辑器&#xff0c;它消除了编译Java代码的步骤。 这个概念并不新鲜&#xff0c;例如在网络世界中&#xff0c;有许多HTML5 游乐场提供在线编辑器&#xff0c;使开发人员可以快速原型化或尝试各种Ja…

Node.js安装及环境配置之Windows篇

原博文链接&#xff1a;Node.js安装及环境配置之Windows篇 - 刘奇云 - 博客园 from:https://www.cnblogs.com/zhouyu2017/p/6485265.html 一、安装环境 1、本机系统&#xff1a;Windows 10 Pro&#xff08;64位&#xff09; 2、Node.js&#xff1a;v6.9.2LTS&#xff08;64位…

npm WARN logfile could not create logs-dir: Error: EPERM: operation not permitted, mkdir ‘地址

场景&#xff1a;在windows系统下&#xff0c;安装node之后&#xff0c;查看npm版本&#xff0c;报错如图所示&#xff1a; 原因&#xff1a;是node目录权限不够&#xff1b; 解决方法&#xff1a;找到node目录&#xff0c;右键属性 > 安全 > 设置users用户完全控制权限…

javafx 自定义控件_JavaFX技巧10:自定义复合控件

javafx 自定义控件用JavaFX编写自定义控件是一个简单直接的过程。 需要一个控件类来控制控件的状态&#xff08;因此命名&#xff09;。 外观需要控件的外观。 而且通常不是用于自定义外观CSS文件。 控件的一种常见方法是将其正在使用的节点隐藏在其外观类中。 例如&#xff0…

虚拟机与容器 的 区别

VM和容器都可以帮助您充分利用可用的计算机硬件和软件资源。容器是块中的新孩子&#xff0c;但VM已经并且将继续在各种规模的数据中心中非常受欢迎。 如果您正在寻找在云中运行自己的服务的最佳解决方案&#xff0c;您需要了解这些虚拟化技术&#xff0c;它们如何相互比较&…