基础算法

本来今天是要讲枚举暴力还有什么的,没想到老师就说句那种题目就猪国杀,还说只是难打,不是难。。。。

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 基础算法的更多相关文章

  1. PHP基础算法

    1.首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半. 思路:多少行for一次,然后在里面空格和星号for一次. <?php for($i=0;$i<=3;$i++ ...

  2. 10个经典的C语言面试基础算法及代码

    10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...

  3. Java基础算法集50题

    最近因为要准备实习,还有一个蓝桥杯的编程比赛,所以准备加强一下算法这块,然后百度了一下java基础算法,看到的都是那50套题,那就花了差不多三个晚自习的时间吧,大体看了一遍,做了其中的27道题,有一些 ...

  4. 贝叶斯公式由浅入深大讲解—AI基础算法入门

    1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生,要么不发生,从来不会去考虑某件事情发生的概率有多大,不发生的概率又是多大.而且概率虽然未知,但最起码是一个确定 ...

  5. 贝叶斯公式由浅入深大讲解—AI基础算法入门【转】

    本文转载自:https://www.cnblogs.com/zhoulujun/p/8893393.html 1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生, ...

  6. java入门学习(3)—循环,选择,基础算法,API概念

    1.顺序结构:也就是顺着程序的前后关系,依次执行.2.选择分支:利用if..else , / switch(){case [ 这个必须是常量]:}; / if..else if….. ….else.. ...

  7. Java - 冒泡排序的基础算法(尚学堂第七章数组)

    /** * 冒泡排序的基础算法 */ import java.util.Arrays; public class TestBubbleSort1 { public static void main(S ...

  8. c/c++面试总结---c语言基础算法总结2

    c/c++面试总结---c语言基础算法总结2 算法是程序设计的灵魂,好的程序一定是根据合适的算法编程完成的.所有面试过程中重点在考察应聘者基础算法的掌握程度. 上一篇讲解了5中基础的算法,需要在面试之 ...

  9. c/c++面试指导---c语言基础算法总结1

    c语言基础算法总结 1  初学者学习任何一门编程语言都必须要明确,重点是学习编程方法和编程思路,不是学习语法规则,语法规则是为编程实现提供服务和支持.所以只要认真的掌握了c语言编程方法,在学习其它的语 ...

  10. ACM基础算法入门及题目列表

    对于刚进入大学的计算机类同学来说,算法与程序设计竞赛算是不错的选择,因为我们每天都在解决问题,锻炼着解决问题的能力. 这里以TZOJ题目为例,如果为其他平台题目我会标注出来,同时我的主页也欢迎大家去访 ...

随机推荐

  1. php微信支付v3版本签名生成

    前几天需要对接微信支付卡包营销活动需要对接微信新版SDKv3版 签名生成规则,微信的官方文档里面说明的还算可以吧,不过个人觉得不太理想- -.  自己调试的时候调试了半天才找了错误原因. https: ...

  2. 配置mysql可局域网内访问

    一 进入mysql输入密码 :mysql -u root -p二 执行可局域网访问命令:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY ...

  3. javascript生成规定范围的随机整数

    Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范围是[0.0,1.0)的左闭右开区间,返回值是一个伪随机选择的数,在该范围内(近似)均匀分布. 我 ...

  4. 毕业生想学习web前端,应该怎么学才能最快找到工作?

    首先无论你要学习任何技能,必须有一个清晰的版图,什么是清晰的版图呢?首先了解你学的技术将来要从事什么工作,这个工作的条件是哪些? 然后你要有一个非常清晰的学习大纲,切记学习任何东西都要系统,不可胡乱的 ...

  5. python犯傻之题目解答思路比较与反思

    1.题目: 企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%: 20万 ...

  6. 关于thinkphp框架中模型笔记

    模型这一块,感觉学习的不是很清楚,单独水一贴thinkphp中模型的学习笔记. 0x01 模型类简介 数据库中每一张表对应一个模型,类名就是表名,类里面的成员变量就是列名, 把一张表对应为一个类,其中 ...

  7. window 后台运行的应用程序点击没反应

    有时候,开了几个软件,有的软件一段时间没点击,再点击软件的图标一点反应都没有,这时,可以试着这么做: window 快捷键 :win + r  , 输入命令 : taskmgr ,打开任务管理器,选择 ...

  8. 使用Docker搭建apache环境

    Docker搭建apache环境 前言 操作机:ubuntu16 x64 Dockers servion 18.09.7 下载镜像 使用docker pull 拉取最新的 apache镜像 命令:do ...

  9. tinyxml2

    网上下载tinyxml2:tinyxml2.h和tinyxml2.cpp 加载xml XMLDocument doc;   doc.LoadFile("test.xml");   ...

  10. linux+jenkins+github+python持续集成

    1.服务器上事先安装jenkins   参见:linux上war包方式安装Jenkins 2.新建一个自由风格的job,名字随意起 3.配置git(拉取github代码) 从github复制pytho ...