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题目为例,如果为其他平台题目我会标注出来,同时我的主页也欢迎大家去访 ...
随机推荐
- 在chrome浏览器中调用IE浏览器并访问(openIE.reg自定义协议)
在谷歌浏览器中有4种方法调用IE浏览器.如下: c++ socket通过浏览器在ie中打开指定url : vb生成exe,url访问exe启动ie并打开指定url : 通过socket实现通过http ...
- HTML块元素与内联元素嵌套规则
HTML存在许多种类型的标签,有的标签下面只允许特定的标签存在,这就叫HTML嵌套规则.不按HTML嵌套规则写,浏览器就不会正确解析,会将不符合嵌套规则的节点放到目标节点的下面,或者变成纯文本.关于H ...
- python编程基础之三十三
构造方法: 目的:构造方法用于初始化对象,可以在构造方法中添加成员属性 触发时机:实例化对象的时候自动调用 参数:第一个参数必须是self,其它参数根据需要自己定义 返回值:不返回值,或者说返回Non ...
- 了解ajax基本爬取方式
'''爬去豆瓣电影数据了解ajax的基本爬去方式 ''' from urllib import requestimport jsonimport ssl url = "https://mov ...
- Bitset改进你的程序质量
1:Bitset介绍 BitSet 是用于存储二进制位和对二进制进行操作的 Java 数据结构, 此类实现了一个按需增长的位向量.位 set 的每个组件都有一个 boolean 值.用非负的整数将 B ...
- Tomcat基本知识(一)
顶层架构先上一张Tomcat的顶层结构图(图A),如下: Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务 ...
- 阿里云 RDS 数据库又发 CPU 近 100% 的“芯脏病”
最近云界发生了2件事,一件是大事,一件是小事,大事是阿里云与微软合作推出了开放应用模型 Open Application Model(OAM),小事是由于微软 SQL Server 在阿里云上水土不服 ...
- 微信小程序发起请求
一.示例代码 wx.request({ url: 'test.php', // 仅为示例,并非真实的接口地址 data: { x: '', y: '' }, header: { 'content-ty ...
- 代码审计-Thinkphp3框架EXP表达式SQL注入
最近看java框架源码也是看的有点头疼,好多还要复习熟悉 还有好多事没做...慢慢熬. 网上好像还没有特别详细的分析 我来误人子弟吧. 0x01 tp3 中的exp表达式 查询表达式的使用格式: $m ...
- Cocos2d-x 学习笔记(3.3) Layer
1.简介 Layer直接继承了Node.Layer类似Ps里图层的概念,也可以理解成一块透明玻璃.Scene类似Ps里的一张图像,也可以理解成堆放玻璃的箱子. Layer能接收触摸事件.键盘事件.加速 ...