DAY 4 基础算法
基础算法
本来今天是要讲枚举暴力还有什么的,没想到老师就说句那种题目就猪国杀,还说只是难打,不是难。。。。
STL(一)set
感觉今天讲了好多,set,单调栈,单调队列,单调栈和单调队列保证了序列的单调性,一般的,凡是找左右第一个比他大或小的大概率是这个东西,原来作业1的奶牛歌声就是这个东西,但不是道为什么我爆力优化过了。。。。
然后就是这题
这题要用set,不用还过不了。。。。
set常用函数
- begin() ,返回set容器的第一个元素
- end() ,返回set容器的最后一个元素
- clear() ,删除set容器中的所有的元素
- empty() ,判断set容器是否为空
- max_size() ,返回set容器可能包含的元素最大个数
- size() ,返回当前set容器中的元素个数
- rbegin ,返回的值和end()相同
- rend() ,返回的值和rbegin()相同
可以这样练下手
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int >s;
s.insert();
s.insert();
s.insert();
s.insert();
cout<<"长度是"<<s.size()<<endl;
cout<<"可能包含元素的最大个数为"<<s.max_size() <<endl;
cout<<"第一个元素是"<< *s.begin()<<endl;
cout<<"最后一个元素是"<<*s.end()<<endl;
s.clear();
if(s.empty())
{
cout<<"空啦!!!!"<<endl;
}
cout<<"长度是"<<s.size()<<endl;
cout<<"可能包含元素的最大个数为"<<s.max_size() <<endl;
}
输出是这样的:
注意如果这样打
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int >s;
s.insert();
s.insert();
s.insert();
s.insert();
cout<<"第一个元素是"<< *s.begin()<<endl;
cout<<"最后一个元素是"<<*s.end()<<endl;
return ;
}
我们可以发现最后一个元素显示还是3.。。
- count() 用来查找set中某个某个键值出现的次数
这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int >s;
s.insert();
s.insert();
s.insert();
s.insert();
cout<<"set 中 1 出现的次数是 :"<<s.count()<<endl;
cout<<"set 中 4 出现的次数是 :"<<s.count()<<endl;
return ;
}
输出应该是这样的
- equal_range() ,返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。
#include <iostream>
#include <set> using namespace std; int main()
{
set<int> s;
set<int>::iterator iter;
for(int i = ; i <= ; ++i)
{
s.insert(i);
}
for(iter = s.begin() ; iter != s.end() ; ++iter)
{
cout<<*iter<<" ";
}
cout<<endl;
pair<set<int>::const_iterator,set<int>::const_iterator> pr;
pr = s.equal_range();
cout<<"第一个大于等于 3 的数是 :"<<*pr.first<<endl;
cout<<"第一个大于 3的数是 : "<<*pr.second<<endl;
return ;
}
输出因该是这样的
- erase(iterator) ,删除定位器iterator指向的值
- erase(first,second),删除定位器first和second之间的值
- erase(key_value),删除键值key_value的值
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
set<int>::const_iterator iter;
set<int>::iterator first;
set<int>::iterator second;
for(int i = ; i <= ; ++i)
{
s.insert(i);
}
//第一种删除
s.erase(s.begin());
//第二种删除
first = s.begin();
second = s.begin();
second++;
second++;
s.erase(first,second);
//第三种删除
s.erase();
cout<<"删除后 set 中元素是 :";
for(iter = s.begin() ; iter != s.end() ; ++iter)
{
cout<<*iter<<" ";
}
cout<<endl;
return ;
return ;
}
输出
- insert(key_value); 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。
- inset(first,second);将定位器first到second之间的元素插入到set中,返回值是void.
- lower_bound(key_value) ,返回第一个大于等于key_value的定位器
- upper_bound(key_value),返回最后一个大于key_value的定位器
非常尴尬的发现就算学了这个东西,那题还是不会。。。。。。。
STL(二)bitset
感觉这个东西还挺好用的,也是STL里的一个神器,感觉好多题目都能用,那个三维偏序好像除了CDQ分治,KD——tree,和bitset都能打。。。还是只占一个字符,比单纯的bool,好用不知道多少。
初始化:
#include<iostream>
#include<bitset>
using namespace std;
int main()
{
bitset<> bitset1;//初始化,长度为4,全都是0
bitset<> bitset2();//长度是8,用二进制存12,不足位补0
string s="";
bitset<> bitset3(s);//同上
cout<<bitset1<<endl;
cout<<bitset2<<endl;
cout<<bitset3<<endl;
return ;
}
输出应该是这样的:
另外,bitset只能存0或1,如果有其他的东西会报错,原来char也可以,但不知道为什么会警告,能不用最好还是不用。。。。
一些常见的位运算:
#include<iostream>
#include<bitset>
using namespace std;
int main()
{
bitset<> bitset1(string(""));
bitset<> bitset2(string(""));
cout<<(bitset1^=bitset2)<<endl;//按位异或后将值付给bitset1
cout<<(bitset1&=bitset2)<<endl;//按位与后将值付给bitset1
cout<<(bitset1|=bitset2)<<endl;//按位或后将值付给bitset1
cout<<(bitset1<<=)<<endl;//右移后将值付给bitset1
cout<<(bitset1>>=)<<endl;//左移后将值付给bitset1
cout<<(bitset1==bitset2)<<endl; //假的,返回false(0)
cout<<(bitset1!=bitset2)<<endl;//真的,返回true(1或-1)
cout<<(bitset2&bitset1)<<endl;//左移后将值付给bitset1 ,其他同理
return ;
}
输出应该是这样的:
还可以像数组那样去访问每一位
一些常用的函数:
这正是STL吸引人的主要原因,可以不用手打,但会慢,对于我这样的蒟蒻就完全不会有影响,但也许对于机房旁边的大佬(传送门)就会有很大影响,这会让他AK不了IOI!!!!
#include<iostream>
#include<bitset>
#include<cstdlib>
#include<cstdio>
#include<bits/stdc++.h>
using namespace std;
int main()
{
bitset<> bitset1(string(""));
cout<<bitset1.count()<<endl;//(count函数用来求bitset中1的位数,foo中共有5个1
cout<<bitset1.size()<<endl;//(size函数用来求bitset的大小,一共有8位
cout<<bitset1.test()<<endl;//(test函数用来查下标处的元素是0还是1,并返回false或true,此处foo[0]为1,返回true
cout<<bitset1.test()<<endl;//(同理,foo[2]为0,返回false
cout<<bitset1.any()<<endl;//(any函数检查bitset中是否有1
cout<<bitset1.none()<<endl;//(none函数检查bitset中是否没有1
cout<<bitset1.all()<<endl;//f(all函数检查bitset中是全部为1
//说明一下:test函数会对下标越界做出检查,而用过数组方式访问的元素则不会,所以用test更安全一些
string s=bitset1.to_string();//将bitset转换成string类型
unsigned long a=bitset1.to_ulong();//将bitset转换成unsigned long类型
cout<<s<<endl;
cout<<a<<endl;
cout<<bitset1.flip()<<endl;//(flip函数传参数时,用于将参数位取反,本行代码将foo下标2处"反转",即0变1,1变0
cout<<bitset1.flip()<<endl;//(flip函数不指定参数时,将bitset每一位全部取反
cout<<bitset1.set()<<endl;//(set函数不指定参数时,将bitset的每一位全部置为1
cout<<bitset1.set(,)<<endl;//(set函数指定两位参数时,将第一参数位的元素置为第二参数的值,本行对foo的操作相当于foo[3]=0
cout<<bitset1.set()<<endl; //(set函数只有一个参数时,将参数下标处置为1
cout<<bitset1.reset()<<endl;//(reset函数传一个参数时将参数下标处置为0
cout<<bitset1.reset()<<endl;//(reset函数不传参数时将bitset的每一位全部置为0
//这些函数同样会检查数组下标,有异常会提示。 return ;
}
贪心:
贪心是个非常有用的东西,有时候没有思路,也不会证明,但乱搞就过了。。。。
bzoj 3668 起床困难综合征(门)
- 从高位到低位枚举每一位,判断是1还是0,位运算各位之间不会影响。
- 保证当前的数不会大于m;
对于0能变为1的两种情况直接变。
0变为的两种情况不予考虑。
代码就非常简单:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+;
char op[];
long long n,m;
long long t;
long long ans=,ans0=,ans1=0x7fffffff;
int main()
{
//freopen("testdata.in","r",stdin);
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s %lld",op,&t);
if(op[]=='A')
{
ans1&=t;
ans0&=t;
}
else
if(op[]=='O')
{
ans1|=t;
ans0|=t;
}
else
if(op[]=='X')
{
ans1^=t;
ans0^=t;
}
}
for(int i=;i>=;i--)
{
if(ans0&(<<i))
{
ans+=(<<i);
}
else
if((m>=(<<i))&&(ans1&(<<i)))
{
m-=(<<i);
ans+=(<<i);
}
}
cout<<ans<<endl;
return ;
}
BZOJ 2563 阿狸和桃子的游戏(门)
这题可以吧边权平分到两边的点,这样相对大小没变,一减也没变。
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e6+;
int sum[maxn];
int x,y,z;
int k;
int ans=;
int n,m;
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++)
{
cin>>k;
sum[i]=k<<;
}
for(int i=;i<=m;i++)
{
cin>>x>>y>>z;
sum[x]+=z;
sum[y]+=z;
}
sort(sum+,sum++n);
for(int i=n;i>=;i-=)
{
ans+=sum[i]-sum[i-];
}
ans/=;
cout<<ans<<endl;
return ;
}
NOIP 2015 跳石头(还是回淮南的测试里的题目)
- 显然这题这题就是二分还是比较经典的哪一类。
- 二分一个答案,看他是否符合条件。
- 贪心
- 从第二块开始循环(第一块不能搬走,要不然你站哪?)假设现在到了第i块,上一个没搬走的是第J块,如果当前的距离小于ans,就可以直接搬走,要不然就留下来。
- 最后一块不能搬走,要不你最后站哪?
快乐的代码时光(机房考试还有人打了线段树,几千字。。。)
NOIP 2012 DAY2 T2 借教室
- 这题好快乐,暴力拿了50分。。。
- 正解还是二分,二分一个答案,看他能满足到哪一个订单。
- 然后把1到ans的所有订单都扫描一下。
- 可以用差分数组优化一下复杂度。
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib> using namespace std; const int maxn=1e6+; int need[maxn];
int sheng[maxn];
int r[maxn];
int l[maxn];
int d1[maxn];
int d2[maxn];
int n,m; int panduan(int x)
{
memset(d2,,sizeof(d2));
for(int i=;i<=x;i++)
{
d2[l[i]]+=d1[i];
d2[r[i]+]-=d1[i];
}
for(int i=;i<=n;i++)
{
need[i]=need[i-]+d2[i];
if(need[i]>sheng[i])
return ;
}
return ;
} int main()
{
memset(d1,,sizeof(d1));
memset(need,,sizeof(need));
memset(sheng,,sizeof(sheng));
memset(l,,sizeof(l));
memset(r,,sizeof(r));
cin>>n>>m;
for(int i=;i<=n;i++)
{
cin>>sheng[i];
}
for(int i=;i<=m;i++)
{
cin>>d1[i]>>l[i]>>r[i];
}
if(panduan(m))
{
cout<<""<<endl;
return ;
}
else
{
int L=,R=m;
while(L<R)
{
int middle=(L+R)/;
if(panduan(middle))
{
L=middle+;
}
else
{
R=middle;
}
}
cout<<"-1"<<endl<<L<<endl;
}
return ;
}
DAY 4 基础算法的更多相关文章
- PHP基础算法
1.首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半. 思路:多少行for一次,然后在里面空格和星号for一次. <?php for($i=0;$i<=3;$i++ ...
- 10个经典的C语言面试基础算法及代码
10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...
- Java基础算法集50题
最近因为要准备实习,还有一个蓝桥杯的编程比赛,所以准备加强一下算法这块,然后百度了一下java基础算法,看到的都是那50套题,那就花了差不多三个晚自习的时间吧,大体看了一遍,做了其中的27道题,有一些 ...
- 贝叶斯公式由浅入深大讲解—AI基础算法入门
1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生,要么不发生,从来不会去考虑某件事情发生的概率有多大,不发生的概率又是多大.而且概率虽然未知,但最起码是一个确定 ...
- 贝叶斯公式由浅入深大讲解—AI基础算法入门【转】
本文转载自:https://www.cnblogs.com/zhoulujun/p/8893393.html 1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生, ...
- java入门学习(3)—循环,选择,基础算法,API概念
1.顺序结构:也就是顺着程序的前后关系,依次执行.2.选择分支:利用if..else , / switch(){case [ 这个必须是常量]:}; / if..else if….. ….else.. ...
- Java - 冒泡排序的基础算法(尚学堂第七章数组)
/** * 冒泡排序的基础算法 */ import java.util.Arrays; public class TestBubbleSort1 { public static void main(S ...
- c/c++面试总结---c语言基础算法总结2
c/c++面试总结---c语言基础算法总结2 算法是程序设计的灵魂,好的程序一定是根据合适的算法编程完成的.所有面试过程中重点在考察应聘者基础算法的掌握程度. 上一篇讲解了5中基础的算法,需要在面试之 ...
- c/c++面试指导---c语言基础算法总结1
c语言基础算法总结 1 初学者学习任何一门编程语言都必须要明确,重点是学习编程方法和编程思路,不是学习语法规则,语法规则是为编程实现提供服务和支持.所以只要认真的掌握了c语言编程方法,在学习其它的语 ...
- ACM基础算法入门及题目列表
对于刚进入大学的计算机类同学来说,算法与程序设计竞赛算是不错的选择,因为我们每天都在解决问题,锻炼着解决问题的能力. 这里以TZOJ题目为例,如果为其他平台题目我会标注出来,同时我的主页也欢迎大家去访 ...
随机推荐
- day 20作业
目录 1.下面这段代码的输出结果将是什么?请解释. 2.多重继承的执行顺序,请解答以下输出结果是什么?并解释. 3.什么是新式类,什么是经典类,二者有什么区别?什么是深度优先,什么是广度优先? 4.用 ...
- 【DP合集】背包 bound
N 种物品,第 i 种物品有 s i 个,单个重量为 w i ,单个价值为 v i .现有一个限重为 W 的背包,求能容 纳的物品的最大总价值. Input 输入第一行二个整数 N , W ( N ≤ ...
- 一个最简单的springboot
现在项目里使用springboot,平时开发并不太关注springboot的一些基本配置,现在想整理一下springboot相关内容. 实际开发中都会因为各种业务需求在springboot上添加很多东 ...
- 【Medium 万赞好文】ViewModel 和 LIveData:模式 + 反模式
原文作者: Jose Alcérreca 原文地址: ViewModels and LiveData: Patterns + AntiPatterns 译者:秉心说 View 和 ViewModel ...
- 机器学习实战_KNN(一)
[是什么] KNN 即 k_近邻算法(k- nearest neighbor) ,就是寻找K个邻居作为该样本的特征,近朱者赤,近墨者黑,你的邻居是什么特征,那么就认为你也具备该特征:核心公式为: 数据 ...
- Cocos2d-x 学习笔记(11.5) SkewTo SkewBy
1. SkewTo SkewBy node朝X和Y方向的歪斜.SkewTo是SkewBy的父类. 1.1 成员变量 create方法 // 两者成员变量一致 float _skewX; float _ ...
- Git推送到多个远程仓库
Git推送到多个远程仓库 Grey 原文地址 准备工作 在码云和Github上分别新建两个不包括任何文件的空仓库(若是两个已经有文件的仓库,请参见关联已经存在的项目) https://github.c ...
- std::wstring
std::wstring主要用于 UTF-16编码的字符, std::string主要用于存储单字节的字符( ASCII字符集 ),但是也可以用来保存UTF-8编码的字符. UTF-8和UTF-16是 ...
- C#详解类型,变量与对象
本节内容: 1.什么是类型(Type) 2.类型在C#语言中的作用 3.C#语言的类型系统 4.变量.对象与内存 1.什么是类型(type) 类型又名数据类型(Date Type),是数据在内存中存储 ...
- javascript学习 first-day
1.javascript是一种客户端语言,设计它的目的是在用户的机器上而不是服务器上执行任务. 1.1 javascript不允许写服务器机器上的语言: 1.2 Javascript不能关闭不是由 ...