基础算法

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

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. CountDownLatch源码及Javadoc阅览

    /** * A synchronization aid that allows one or more threads to wait until * a set of operations bein ...

  2. badboy录制脚本

    第一步:介绍badboy工具 1.1: 页面功能分析: 1. 界面视图,模拟浏览器,能够进行操作 2. 需要录制脚本的URL 3. 点击运行URL 4. Summary:运行的各指标,响应时间,成功事 ...

  3. python requests简单接口自动化

    get方法 url:显而易见,就是接口的地址url啦 headers:定制请求头(headers),例如:content-type = application/x-www-form-urlencode ...

  4. postman全局变量设置

    1.点击小齿轮进入到变量添加页面,点击Globals添加全局变量 2.输入变量名称和变量值 3.接口中设置变量

  5. 构造函数语义学——Copy Constructor 篇

    构造函数语义学--Copy Constructor 篇 本文主要介绍<深度探索 C++对象模型>之<构造函数语义学>中的 Copy Constructor 构造函数的调用时机 ...

  6. postman简单介绍

  7. c#菜单动态合并

    说明 在程序中经常使用弹出菜单,并且一个窗体中可以存在多个弹出菜单.开发过MDI窗体的读者可能都知道,当MDI子窗体最大化时,子窗体和主窗体的菜单能够自动的合并.这是如何实现的呢?本例实现了将两个弹出 ...

  8. 百万年薪python之路 -- HTML基础

    一. Web标准 web标准: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web标准规范的分类:结构标准.表现标准.行为标准. 结构:html.表示:c ...

  9. SpringBoot系列教程之Bean之指定初始化顺序的若干姿势

    上一篇博文介绍了@Order注解的常见错误理解,它并不能指定 bean 的加载顺序,那么问题来了,如果我需要指定 bean 的加载顺序,那应该怎么办呢? 本文将介绍几种可行的方式来控制 bean 之间 ...

  10. Redis备忘(一)

    hash: 渐进式rehash:同时查询新旧两个hash,然后在后续定时任务以及hash的子指令中,循序渐进将旧的迁移到新的hash表 Redis应用: 1.分布式锁: 实现1:setnx+expir ...