算法练习 Week1
1 . 前缀和:
前缀和是一个速度极快的算法,复杂度只有O(1),是在输入的过程中将加和运算完成,计算第i到第j个元素时,只需要将sum[j]-sum[i-1](如果下标从1开始)。
//假设输入n个元素:
int sum[100] = {0};
for(int i=1;i<=n;i++)
{cin>>a[i];sum[i]+=a[i];
}
//设ans为第i个到第j个的和
int ans;
ans = sum[j] - sum[i-1];
例题:
给定一个长度为 n的数组 a1,a2,…,a。现在,要将该数组从中间截断,得到三个非空子数组。要求,三个子数组内各元素之和都相等。请问,共有多少种不同的截断方法?输入格式
第一行包含整数 n。
第二行包含 n个整数 a1,a2,…,an。输出格式
输出一个整数,表示截断方法数量。数据范围
前六个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤105,−10000≤ai≤10000。输入样例1:
4
1 2 3 3
输出样例1:
1
输入样例2:
5
1 2 3 4 5
输出样例2:
0
输入样例3:
2
0 0
输出样例3:
0
这道题思路比较简单,首先判断是否能被3整除。然后从一端先找到sum/3的点,再从另一端寻找sum/3的点。求和的过程中可以应用前缀和。
#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;typedef long long LL;
const int N = 100010;int n;
int s[N];int main(){cin>>n;for(int i=1;i<=n;i++){cin>>s[i];s[i] += s[i-1];}if(s[n]%3){cout<<0;return 0;}LL res = 0;for(int i=3,cnt = 0;i<=n;i++){if(s[i - 2] == s[n]/3) cnt++;if(s[n] - s[i-1] == s[n]/3) res+=cnt; //先统计再结尾是sum/3之前有几个sum/3已经出现,代码更简洁}cout<<res;return 0;
}
2.差分:
差分可以从整体的角度观察变化次数,适用于结果与次数相关联的题目。
差分的实现是将所加区间的左端点++,右端点后--,这样在区间数字的值会++,通过这个区间后,数字的值又会减减。
例题:
给定一个空数组 V和一个整数数组 a1,a2,…,an。现在要对数组 V进行 n次操作。
第 i次操作的具体流程如下:从数组 V尾部插入整数 0。
将位于数组 V末尾的 ai个元素都变为 1(已经是 1的不予理会)。
注意:
ai可能为 0,即不做任何改变。
ai可能大于目前数组 V所包含的元素个数,此时视为将数组内所有元素变为 1。
请你输出所有操作完成后的数组 V。输入格式
第一行包含整数 T,表示共有 T组测试数据。
每组数据第一行包含整数 n。
第二行包含 n个整数 a1,a2,…,an。输出格式
每组数据输出一行结果,表示所有操作完成后的数组 V,数组内元素之间用空格隔开。数据范围
1≤T≤20000,
1≤n≤2×105,
0≤ai≤n,
保证一个测试点内所有 n的和不超过 2×105。输入样例:
3
6
0 3 0 0 1 3
10
0 0 0 1 0 5 0 0 0 2
3
0 0 0
输出样例:
1 1 0 1 1 1
0 1 1 1 1 1 0 0 1 1
0 0 0
当一个位置改变奇数次时为他本身,改变偶数次时为1。
#include<iostream>
#include<string.h>
#include<algorithm>using namespace std;const int N = 200100;int n;
int b[N];int main()
{int T;cin>>T;while(T--){cin>>n;memset(b,0,(n+1)*4);for(int i=1;i<=n;i++){int a;cin>>a;int l = max(1,i-a+1),r = i;b[l]++,b[r+1]--;}for(int i=1;i<=n;i++){b[i]+=b[i-1];cout<<!!b[i]<<" "; //此处两次取反是为了防止b[i]的值大于1}cout<<endl;}return 0;
}
3.二分查找:
当数据具有范围性或者单调性时,可以使用二分查找,复杂度Olog(n),使用二分查找时,一定要注意左右边界变化的问题。如果有一点点失误,就会陷入死循环。
例题:
农夫约翰出门沿着马路散步,但是他现在发现自己可能迷路了!沿路有一排共 N个农场。
不幸的是农场并没有编号,这使得约翰难以分辨他在这条路上所处的位置。
然而,每个农场都沿路设有一个彩色的邮箱,所以约翰希望能够通过查看最近的几个邮箱的颜色来唯一确定他所在的位置。
每个邮箱的颜色用 A..Z之间的一个字母来指定,所以沿着道路的 N个邮箱的序列可以用一个长为 N的由字母 A..Z组成的字符串来表示。
某些邮箱可能会有相同的颜色。
约翰想要知道最小的 K的值,使得他查看任意连续 K个邮箱序列,他都可以唯一确定这一序列在道路上的位置。例如,假设沿路的邮箱序列为 ABCDABC 。约翰不能令 K=3,因为如果他看到了 ABC,则沿路有两个这一连续颜色序列可能所在的位置。
最小可行的 K的值为 K=4,因为如果他查看任意连续4 个邮箱,那么可得到的连续颜色序列可以唯一确定他在道路上的位置。输入格式
输入的第一行包含 N,第二行包含一个由 N个字符组成的字符串,每个字符均在 A..Z之内。输出格式
输出一行,包含一个整数,为可以解决农夫约翰的问题的最小 K值。数据范围
1≤N≤100输入样例:
7
ABCDABC
输出样例:
4
此题寻找的是最小不重复字符串,如果相连的n个字符串都不能重复,那么>n时,一定找不到重复字符串。寻找字符串时使用substr函数和哈希表查找。二分时候要格外小心。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_set>using namespace std;int n;
string str;bool check(int mid){unordered_set<string> hash;for(int i=0 ;i+mid-1<str.size();i++){auto s = str.substr(i,mid); //取相连的字符串if(hash.count(s)) return false; //寻找字符串是否存在hash.insert(s);}return true;
}int main(){cin>>n;cin>>str;int l = 1;int r = n;while(l<r){int mid = l + r >>1; //移位进行简单运算if(check(mid)) r = mid; else l = mid +1; //如果不在范围内,就讲左值跳出范围}cout<<r<<endl;return 0;
}
4 . 双指针:
不断查询连续3个相连x的情况即可。
#include <bits/stdc++.h>
using namespace std;int main() {int n;string s;cin >> n >> s;int ret = 0, cnt = 0;for(int i = 0; i < n; i++) {if(s[i] == 'x') {cnt++;if(cnt == 3) {ret++;cnt--; //如果满3个就将减掉一个}} else {cnt = 0; //如果连不上3个,就归零}}cout << ret << endl;return 0;
}
5 . 递推:
递推具有一定的灵活性,主要可以用于按某种规律依次操作的题型。
例题:
此题可以将可行的尝试列举出来,观察最后一个是否符合要求,就可以判断是否成立。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>using namespace std;const int N = 100010;int n;void update(char&c)
{if(c == 'W') c = 'B';else c = 'W';
}bool check(string s,char c)
{vector <int> res;for(int i=0;i<n-1;i++){if(s[i]!=c){update(s[i]);update(s[i+1]);res.push_back(i); //用于储存数据,将已经走过的点储存在vector中}}if(s.back()!= s[0]) return false;cout<<res.size()<<endl;for(auto x:res) cout<<x+1<<' ';if(res.size()) cout<<endl;return true;
}int main()
{int T;cin>>T;while(T--){string s;cin>>n>>s;if(!check(s,'W') && !check(s,'B')) puts("-1"); //判断两种方法可行性}
}
算法练习 Week1相关推荐
- 2022 七校联合NewStarCTF 公开赛赛道 WEEK3|MISC
1.Whats HTTP 2.qsdz's girlfriend 3 3.WebShell! hint提示蚁剑,根据流量包大小排序,逐个打开看 4.Yesec no drumsticks 3 压缩包第 ...
- 斯坦福-随机图模型-week1.0_
title: 斯坦福-随机图模型-week1.0 tags: note notebook: 6- 英文课程-9-Probabilistic Graphical Models 1: Representa ...
- 深度探索推荐系统算法在工业界如何应用
由于近些年深度学习技术的飞速发展,大力加速推动了AI在互联网以及传统各个行业的商业化落地,尤其是推荐系统.计算广告等领域.由于推荐系统与提升用户量以及商业化变现有着密不可分的联系,各大公司都放出了众多 ...
- 【限时】推荐算法工程师培养计划
由于近些年深度学习技术的飞速发展,大力加速推动了AI在互联网以及传统各个行业的商业化落地,其中,推荐系统.计算广告等领域彰显的尤为明显.由于推荐系统与提升用户量以及商业化变现有着密不可分的联系,各大公 ...
- 备战秋招 |《百面机器学习》算法+leetcode开班报名!
算法面试刷题班推荐: 以<百面机器学习>为教材 结合leetcode筛选刷题 秋招已经开始了!时间紧迫,也许别人已经得到offer了,你却还在不知所措?(文末重金招聘讲师) 六月份基本都是 ...
- 仅剩3天 | 带学《百面机器学习》葫芦书,算法+leetcode一应俱全
或许你只要比别人准备多一点,你就可以在群体中脱颖而出. 年后基本都是春招和社招的高峰期,但好岗位招聘人数和应聘人数简直堪比春运抢票. 你总在抱怨"为什么别人机会那么好,能抢到你想要的名额?& ...
- mooc- 基本程序设计方法week1,week2
学习了第一单元我们几本可以写出10行左右的代码. week1:python编程之基本方法 1.从计算机到程序设计语言: 理解计算机:计算机是能够根据一组指令操作数据的机器. 功能性:可以进行数据计算 ...
- 国内最强算法推荐系统,这波稳了!
由于近些年深度学习技术的飞速发展,大力加速推动了AI在互联网以及传统各个行业的商业化落地,尤其是推荐系统.计算广告等领域.由于推荐系统与提升用户量以及商业化变现有着密不可分的联系,各大公司都放出了众多 ...
- [buaa-SE-2017]个人作业-Week1
个人作业-Week1 Part1:教材中不懂的问题 1.根据书中"除了前20的学校之外,计科和软工没有区别"所以计算机科学这个专业也许在我们学校是和软件工程有区别的,但是可以料想的 ...
最新文章
- 记一次订单号重复的事故,快看看你的 uuid 在并发下还正确吗?
- python中datetime模块常用方法_Python中datetime的使用和常用时间处理
- 20154318_王秀飞 Exp2 后门原理与实践
- sudoers修改_Ubuntu修改sudoers文件导致sudo命令无法使用的拯救方法
- 一份其实很短的 LaTeX 入门文档
- 2019年10个最受欢迎的JavaScript动画库!
- 【图像】Dog(高斯差分)检测角点
- PyCharm编写shell脚本无法运行
- linux 同步IO: sync msync、fsync、fdatasync与 fflush
- 从“嵌入式”到“物联网”有哪些变化?
- oracle数据库函数手册,Oracle分析函数参考手册(转)
- 补偏救弊 | 关于一致性读与语句性能关系的一大误区
- redis中不同value类型的存取操作方式
- MySQL引擎详解(二)——MyISAM引擎特性
- COCOS2D-X 不反复随机数
- ubuntu 时间戳不对
- [leetcode题解] 第995题Minimum Number of K Consecutive Bit Flips
- 腾讯视频 Node.js 服务是如何支撑国庆阅兵直播高并发的?
- 游戏开发常用引擎工具介绍对比区别(UE4,Unity,Cocos,LayaAir,[egret白鹭])
- java.io.IOException: 设备未就绪