1,线段树查找区间最大值和区间和:
#include<iostream>
#include<cstring>
# define MAXN 2000005
int maxx;
using namespace std;
struct node
{
int left;
int right;
int value;
} q[MAXN];
int father[MAXN];
void BuildTree(int i,int l,int r)
{
q[i].left=l;
q[i].right=r;
q[i].value=0;
if(l==r)
{
father[l]=i;
return ;
}
BuildTree(i<<1,l,(l+r)/2);
BuildTree((i<<1)+1,(l+r)/2+1,r);
}
void UpdateTree(int ri)
{
if(ri==1)
{
return ;
}
int fi=ri/2;
int a=q[fi*2].value;
int b=q[fi*2+1].value;
q[ri/2].value=max(a,b);
UpdateTree(ri/2);
}
void FindMax(int i,int l,int r)
{
if(q[i].left==l&&q[i].right==r)
{
maxx=max(maxx,q[i].value);
return ;
}
i=i<<1;
if(l<=q[i].right)
{
if(r<=q[i].right)
{
FindMax(i,l,r);
}
else if(r>q[i].right)
{
FindMax(i,l,q[i].right);
}
}
i++;
if(r>=q[i].left)
{
if(l>=q[i].left)
{
FindMax(i,l,r);
}
else
FindMax(i,q[i].left,r);
}
}
int main()
{
int n,m;
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
BuildTree(1,1,n);
for(int i=1; i<=n; i++)
{
int temp;
cin>>temp;
q[father[i]].value=temp;
UpdateTree(father[i]);
}
while(m--)
{
char str;
int u,v;
cin>>str>>u>>v;
if(str=='Q')
{
maxx=0;
FindMax(1,u,v);
cout<<maxx<<endl;
}
else
{
q[father[u]].value=v;
UpdateTree(father[u]);
}
}
}
return 0;
}
查找区间和代码:
#include<iostream>#include<cstring>
# define MAXN 2000005
int maxx;
int res;
using namespace std;
struct node
{
int left;
int right;
int value;
} q[MAXN];
int father[MAXN];
void BuildTree(int i,int l,int r)
{
q[i].left=l;
q[i].right=r;
q[i].value=0;
if(l==r)
{
father[l]=i;
return ;
}
BuildTree(i<<1,l,(l+r)/2);
BuildTree((i<<1)+1,(l+r)/2+1,r);
}
void UpdateTree(int ri)
{
if(ri==1)
{
return ;
}
int fi=ri/2;
int a=q[fi*2].value;
int b=q[fi*2+1].value;
q[ri/2].value=a+b;
UpdateTree(ri/2);
}
void Query(int i,int l,int r)
{
if(q[i].left==l&&q[i].right==r)
{
res+=q[i].value;
// maxx=max(maxx,q[i].value);
return ;
}
i=i<<1;
if(l<=q[i].right)
{
if(r<=q[i].right)
{
Query(i,l,r);
}
else
{
Query(i,l,q[i].right);
}
}
i++;
if(r>=q[i].left)
{
if(l>=q[i].left)
{
Query(i,l,r);
}
else
Query(i,q[i].left,r);
}
}
int main()
{
int n,m;
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
BuildTree(1,1,n);
for(int i=1; i<=n; i++)
{
int temp;
cin>>temp;
q[father[i]].value=temp;
UpdateTree(father[i]);
}
while(m--)
{
res=0;
char str[100];
int u,v;
cin>>str>>u>>v;
if(str[0]=='Q')
{
Query(1,u,v);
cout<<res<<endl;
}
else
{
q[father[u]].value+=v;
UpdateTree(father[u]);
}
}
}
return 0;
}
2,map初级使用 map的基本操作函数:
C++ Maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
map的基本操作函数:
C++ Maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
二、插入数据
插入数据之前先说一下pair 和 make_pair 的用法
pair是一个结构体,有first和second 两个域,可以直接访问
1 string key="sunquan"; 2 int value=123456; 3 pair <string,int> b(key, value);//这里 pair <string,string>是数据类型,后面是调带参构造方法 4 cout<<b.first<<endl;
而make_pair是返回一个pair <类型,类型> 的数据,eg:make_pair("asa",123456); 不过还得找个pair <string,int>类型的变量来接受返回值。
下面步入正题:
(1) Map["abc"]=1;
(2) Map.insert(pair<string,int>("c",3));
(3)Map.insert(make_pair<string,int>("d",4));
三、修改和查找数据
(1)修改Map["sunquan"]=11111;
(2)查找数据 用Map.find(key); 可以通过键来查。
切记不要用int value=Map[key];这样会在Map中增加这个key,而value就是缺省值(int 为0,string为空字符串)。
通过方法(2),会返回迭代器的地址,key不存在的话迭代器的值为Map.end();
四、删除元素
(1)通过key删除;
(2)通过迭代器来删除;
下面看一下详细的代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <map> 6 using namespace std; 7 8 int main() 9 { 10 map<string,int> Map; 11 map<string,int> ::iterator it; 12 Map.insert(pair<string,int>("root",12)); 13 Map.insert(pair<string,int>("scot",11)); 14 for(it=Map.begin();it!=Map.end();it++) 15 cout<<it->first<<" "<<it->second<<endl; 16 it=Map.begin(); 17 Map.erase(it);//通过迭代器删除 18 string key="root"; 19 Map.erase(key);//通过key删除 20 21 Map.erase(Map.begin(),Map.end());//一个迭代器,到另一个迭代器 22 //相当于 Map.clear(); 23 24 for(it=Map.begin();it!=Map.end();it++) 25 cout<<it->first<<" "<<it->second<<endl; 26 return 0; 27 }
在优先队列中,优先级高的元素先出队列。
标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
优先队列的第一种用法,也是最常用的用法:
通过<操作符可知在整数中元素大的优先级高。
故示例1中输出结果为:9 6 5 3 2
第二种方法:
在示例1中,如果我们要把元素从小到大输出怎么办呢?
这时我们可以传入一个比较函数,使用functional.h函数对象作为比较函数。
其中
第二个参数为容器类型。
第二个参数为比较函数。
故示例2中输出结果为:2 3 5 6 9
第三种方法:
自定义优先级。
{
friend bool operator < (node n1, node n2)
{
return n1.priority < n2.priority;
}
int priority;
int value;
};
在该结构中,value为值,priority为优先级。
通过自定义operator<操作符来比较元素中的优先级。
在示例3中输出结果为:
优先级 值
9 5
8 2
6 1
2 3
1 4
但如果结构定义如下:
{
friend bool operator > (node n1, node n2)
{
return n1.priority > n2.priority;
}
int priority;
int value;
};
则会编译不过(G++编译器)
因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
而且自定义类型的<操作符与>操作符并无直接联系,故会编译不过。
//代码清单
#include < functional >
#include < queue >
using namespace std;
struct node
{
friend bool operator< (node n1, node n2)
{
return n1.priority < n2.priority;
}
int priority;
int value;
};
int main()
{
const int len = 5;
int i;
int a[len] = {3,5,9,6,2};
//示例1
priority_queue<int> qi;
for(i = 0; i < len; i++)
qi.push(a[i]);
for(i = 0; i < len; i++)
{
cout<<qi.top()<<" ";
qi.pop();
}
cout<<endl;
//示例2
priority_queue<int, vector<int>, greater<int> >qi2;
for(i = 0; i < len; i++)
qi2.push(a[i]);
for(i = 0; i < len; i++)
{
cout<<qi2.top()<<" ";
qi2.pop();
}
cout<<endl;
//示例3
priority_queue<node> qn;
node b[len];
b[0].priority = 6; b[0].value = 1;
b[1].priority = 9; b[1].value = 5;
b[2].priority = 2; b[2].value = 3;
b[3].priority = 8; b[3].value = 2;
b[4].priority = 1; b[4].value = 4;
for(i = 0; i < len; i++)
qn.push(b[i]);
cout<<"优先级"<<'\t'<<"值"<<endl;
for(i = 0; i < len; i++)
{
cout<<qn.top().priority<<'\t'<<qn.top().value<<endl;
qn.pop();
}
return 0;
}
C++ STL list的初始化、添加、遍历、插入、删除、查找、排序、释放
list是C++标准模版库(STL,Standard Template Library)中的部分内容。实际上,list容器就是一个双向链表,可以高效地进行插入删除元素。
使用list容器之前必须加上STL的list容器的头文件:#include<list>;
list属于std命名域的内容,因此需要通过命名限定:using std::list;也可以直接使用全局的命名空间方式:using namespace std;
(1)初始化
typedef struct info_s
{
int nNumber;
}info_t;
typedef std::list< info_t > list_t;
定义list的类型
list_t List; //定义一个空的链表
list_t List(count); //建一个含count个默认值是0的元素的链表
list_t List(count, info); //建一个含count个默认值是info的元素的链表
list_t List(List2); //建一个的copy链表
list_t List(List2.begin(),List2.end()); //含区间的元素[First,Last]
(2)添加(添加到末尾)
info_t info;
//Set(info)
List.push_back(info);
将会添加到末尾
(3)遍历
list_t::iterator iter;
for(iter = List.begin(); iter != List.end() ;iter++)
{
std::cout<< iter->nNumber <<std::endl;
}
(4)删除末尾元素
c++的stl list提供pop_back()函数来删除最后一个元素。
List.pop_back();
(5)删除所有元素
简单粗暴的方法:调用clear()
List.clear();
遍历删除法,一个一个删除,这样的好处是,如果元素有申请内容或者系统资源,我们可以把他释放了,避免资源泄漏。
list_t::iterator iter;
for(iter = List.begin(); iter != List.end() ;)
{
//这里可以做是否内存或者资源的操作
//
iter = List.erase(iter);
//iter指向了下一个元素
}
(6)插入
iter = List.insert(iter , info);
插入后iter指向新插入的元素。
(7)查找
list_t::iterator iter ;
iter = std::find(List.begin(),List.end(), info);
if(iter != List.end())
{
std::cout<<"find it"<<std::endl;
}
else
{
std::cout<<"not find it"<<std::endl;
}
注意结构体需要重载==运算符
(8)排序
List.sort();
注意,结构体需要重载运算符<
上代码
- #include <iostream>
- #include <list>
- #include <algorithm>
- #include <stdlib.h>
- #include <string.h>
- typedef struct info_s
- {
- int nNumber;
- bool operator==(struct info_s b) const
- {
- return this->nNumber == b.nNumber;
- }
- bool operator!=(struct info_s b) const
- {
- return this->nNumber != b.nNumber;
- }
- bool operator>=(struct info_s b) const
- {
- return this->nNumber >= b.nNumber;
- }
- bool operator<=(struct info_s b) const
- {
- return this->nNumber <= b.nNumber;
- }
- bool operator>(struct info_s b) const
- {
- return this->nNumber > b.nNumber;
- }
- bool operator<(struct info_s b) const
- {
- return this->nNumber < b.nNumber;
- }
- }info_t;
- typedef std::list< info_t > list_t;
- void append(list_t &List, info_t &info)
- {
- std::cout<<"***append****"<<std::endl;
- List.push_back(info);
- }
- void for_each(list_t &List)
- {
- std::cout<<"***for_each****"<<std::endl;
- list_t::iterator iter;
- for(iter = List.begin(); iter != List.end() ;iter++)
- {
- std::cout<< iter->nNumber <<std::endl;
- }
- }
- void del_end_info(list_t &List)
- {
- std::cout<<"***del_end_info****"<<std::endl;
- if(! List.empty())
- {
- List.pop_back();
- }
- }
- void for_each_delete(list_t &List)
- {
- list_t::iterator iter;
- for(iter = List.begin(); iter != List.end() ;)
- {
- std::cout<< "delete before iter->number:"<<iter->nNumber <<std::endl;
- iter = List.erase(iter);
- std::cout<< "delete after iter->number:"<< iter->nNumber <<std::endl;
- }
- }
- int insert_one(list_t &List , info_t &info, int iPlace)
- {
- int i = 0;
- std::cout<<"insert_one"<<std::endl;
- if(iPlace < 0)
- {
- std::cout<<"insert_one param error"<<std::endl;
- return -1;
- }
- list_t::iterator iter = List.begin();
- while(iter != List.end())
- {
- //std::cout<<" dump "<< (*iVector)<<std::endl;
- if(i == iPlace)
- {
- iter = List.insert(iter , info); //此时insert的返回值是迭代器,插入成功后iVector指向插入的位置
- std::cout<<" insert_one after List point "<<iter->nNumber <<std::endl;
- return 0;
- }
- i++;
- ++iter;
- }
- iter = List.insert(List.end() , info);
- return 0;
- }
- void find_one(list_t &List,info_t info )
- {
- std::cout<<"find_one"<<std::endl;
- list_t::iterator iter ;
- iter = std::find(List.begin(),List.end(), info);
- if(iter != List.end())
- {
- std::cout<<"find it"<<std::endl;
- }
- else
- {
- std::cout<<"not find it"<<std::endl;
- }
- }
- void Sort(list_t & List)
- {
- std::cout<<"Sort it"<<std::endl;
- List.sort();
- for_each(List);
- }
- int main()
- {
- //初始化
- list_t List;
- info_t info;
- memset(&info, 0, sizeof(info_t));
- //添加
- info.nNumber = 8;
- append(List, info);
- info.nNumber = 5;
- append(List, info);
- info.nNumber = 7;
- append(List, info);
- info.nNumber = 1;
- append(List, info);
- info.nNumber = 1;
- append(List, info);
- info.nNumber = 2;
- append(List, info);
- info.nNumber = 1;
- append(List, info);
- //遍历
- for_each(List);
- //插入
- info.nNumber = 80;
- insert_one(List,info,3);
- for_each(List);
- //查找
- find_one(List,info);
- //排序
- Sort(List);
- //删除末尾
- del_end_info(List);
- for_each(List);
- std::cout<< " size:"<<List.size()<<std::endl;
- //删除所有
- // List.clear();
- for_each_delete(List);
- for_each(List);
- std::cout<< " size:"<<List.size()<<std::endl;
- return 0;
- }
这个题的大意就是:每一列座位可以做两个人。已知有两种人,第一种人是在两个座位都是空的条件下,做尺寸偏小的哪一个。第二种人是在两个座位中有一个座位已经有人的前提下,做尺寸偏大的那一个。
输入座位的排数,以及每一排座位的尺寸,以及上车的人的类型,然后让你输出每一个上车的人的选择。
具体思路:对于第一种人而言,只是选空座位中最小的那一个,所以我们可以将空座位打进结构体里面,对于第二种人,因为有座位的排数是逐渐增加的,每一次增加都需要从中选择出尺寸最大的那一个,所以可以将有座位的排数打进优先队列里。
代码如下:
#include<bits/stdc++.h>using namespace std;
char str[400001];
struct node
{
int wi;
int id;
bool friend operator < (const node u,const node v)
{
return u.wi<v.wi;
}//这个地方有些疑问,优先队列里面需要进行降序,正常的话应该是">"号,为什么这里是"<"号?是因为这个是队列,然后输出的时候是从底部开始的原因?
} q[200001];
bool cmp(const node u,const node v)
{
return u.wi<v.wi;
}
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>q[i].wi;
q[i].id=i;
}
priority_queue<node >p;
sort(q+1,q+n+1,cmp);//对空座位进行排序
cin>>str+1;
int t=1;
for(int i=1; i<=2*n; i++)
{
if(str[i]=='0')
{
cout<<q[t].id;
p.push(q[t++]);//每当有一个空座位做上人的时候,这排座位就变成了第二种情况,所以需要把这个座位放进优先队列里
}
if(str[i]=='1')
{
cout<<p.top().id;
p.pop();
}
if(i!=2*n)
cout<<" ";
}
return 0;
}
int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, };
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0Sample Output
(0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (3, 4) (4, 4)
代码:(初级)
#include<iostream>#include<cstring>
using namespace std;
struct node
{
int xi,yi,HeaderNum;
} q[10000];
int a[30][30];
int visited[30][30];
void print(int t1)
{
if(t1!=-1)
{
print(q[t1].HeaderNum);
cout<<"("<<q[t1].xi<<", "<<q[t1].yi<<")"<<endl;
}
}
int main()
{
memset(visited,0,sizeof(visited));
for(int i=0; i<5; i++)
for(int j=0; j<5; j++)
cin>>a[i][j];
int second=1;
q[1].xi=0;
q[1].yi=0;
q[1].HeaderNum=-1;
visited[0][0]=1;
for(int first=1;first<20; first++)
{
int temp1=q[first].xi;
int temp2=q[first].yi;
if(temp1==4&&temp2==4)
{
print(first);
break;
}
// cout<<"**"<<visited[temp1+1][temp2]<<" "<<a[temp1+1][temp2]<<endl;
if(temp1+1<5&&visited[temp1+1][temp2]==0&&a[temp1+1][temp2]==0)
{
visited[temp1+1][temp2]=1;
q[++second].HeaderNum=first;
q[second].xi=temp1+1;
q[second].yi=temp2;
}
if(temp1-1>=0&&visited[temp1-1][temp2]==0&&a[temp1-1][temp2]==0)
{
visited[temp1-1][temp2]=1;
q[++second].xi=temp1-1;
q[second].yi=temp2;
q[second].HeaderNum=first;
}
if(temp2+1<5&&visited[temp1][temp2+1]==0&&a[temp1][temp2+1]==0)
{
visited[temp1][temp2+1]=1;
q[++second].xi=temp1;
q[second].yi=temp2+1;
q[second].HeaderNum=first;
}
if(temp2-1>=0&&visited[temp1][temp2-1]==0&&a[temp1][temp2-1]==0)
{
visited[temp1][temp2-1]=1;
q[++second].xi=temp1;
q[second].yi=temp2-1;
q[second].HeaderNum=first;
}
}
return 0;
}