刷题总结/学习
头文件 #include<bits/stdc++.h>
string
基础知识
-
cin,cout 直接输出整个string
-
字符串的拼接: str1+str2
-
string类的所有字符串都是常量, 不能单独改变其中的一个字符, 但可以访问
-
sort(arr.begin(),arr.end()); sort(arr.begin()+4,arr.end()+8); //4,8对应数组下标, 对下标4-7排序
获取长度
串名.length()
串名.size()
删除元素
删除单个元素
- 按序号
string str="abcdef";
str.erase(str.begin()+2);
//删除第三个元素
//用法:串名 .erase(串名.begin()+n);n为要删除的第n个元素-1;
cout<<str<<endl; //abdef
- 指定元素
使用remove,代码如下:(删除[begin,end)之间的所有值等于’a’的值.)
string str=“aadfgggh”;
str.erase(remove(str.begin(),str.end(),'a'),str.end());
//在容器中, 删除[begin,end)之间的所有值等于’a’的值.
删除区间元素
DFS
例题:
有一个大小n*m的二维迷宫, #表示墙壁, *表示有路可走,每一次可以上下左右移动,问从左上角能否走到右下角:
**####
#**###
##**##
###**#
####**
以下是大致模板,非完整代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 505;
int dx[4] = {0,0,-1,1};
int dy[4] = {-1,1,0,0};
int mapp[maxn][maxn];//存储地图
int flag[maxn][maxn];//标记是否走过
bool check(int x,int y) //判断能不能走
{
if(x>=0 && y>=0 && x<n && y<m && mapp[x][y] == '*' && flag[x][y] == 0)
return true; //n m 地图大小
return false;
}
int edx,edy;
bool dfs(int x,int y)
{
if(!check(x,y))
return false;
if(x == edx && y == edy) return true;
flag[x][y] = 1; //标记成已经走过的点
for(int i = 0;i<4;i++)
{
if(dfs(x+dx[i]),y+dy[i])
return true;
}
return false;
}
int main()
{
int x,y;
scanf("%d%d%d%d",&x,&y,&edx,&edy);
dfs(x,y);
}
/*
参考 Hdu-1241
连通块问题:统计连通块个数
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 509;
char mapp[maxn][maxn];
int n,m;//地图大小
//向四周(包括斜方
int dx[8] = {0,0,-1,1,1,1,-1,-1};
int dy[8] = {-1,1,0,0,1,-1,1,-1};
bool check(int x,int y)
{
if(x>=0 && x<n && y>=0 && y<m && mapp[x][y] == '@')
return 1;
return 0;
}
void dfs(int x,int y)
{
if(!check(x,y)) return;
mapp[x][y] = '*';
for(int i = 0;i<8;i++)
dfs(x+dx[i],y+dy[i]);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n == 0 && m == 0) break;
for(int i = 0;i<n;i++)
scanf("%s",mapp[i]);
int res = 0;
for(int i = 0;i<n;i++)
for(int j = 0;j<n;j++)
if(mapp[i][j] == '@')
{
res++;
dfs(i,j);
}
printf("%d\n",res);
}
}
BFS
通常采用queue实现
当向队列中压入一个元素时,就像排队一样,新来的要排在末尾.
当队列取走一个元素时,取出的是队列中最早压入的那个,就像排队,先来的先走
总之: 先进先出
找最短路径
#include<queue>
//声明
queue<int> q;
//向队列末端压入元素
q.push(3);
/*
BFS:
广度优先,层次遍历,一层一层扩展
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 505;
int mapp[maxn][maxn];//存图
int step[maxn][maxn]; //层数:到起点的最短距离
int vis[maxn][maxn]; //标记是否走过
int n,m;
bool check(int x,int y)
{
if(x>0 && x<=n && y>0 && y<=m && mapp[x][y] == 0 && vis[x][y] == 0)
return true;
return false;
}
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
typedef pair<int,int> PII;
/*
pair<int,int> pi;
pi.first = 1;
pi.second = 2;
一个pair里面有两个元素 ;类似struct pi{ int x; int y};
*/
queue<PII> qq;
PII st,ed,in; //ed就是要找的那个点
int bfs(int x,int y)
{
while(!qq.empty())
{
qq.pop();
}
memset(vis ,0,sizeof(vis));
qq.push(st);//把开始的放进去
vis[st.first][st.second] = 1; //走过 = 1;
step[st.first][st.second] = 0;
while(!qq.empty())
{
PII t = q.front(); //取队首
qq.pop(); //然后出队
if(t.first == ed.first && t.second == ed.second)
{
return step[t.first][t.second];
}
for(int i = 0; i<4;i++)
{
in.first = t.first + dx[i];
in.second = t.second + dy[i];
if(check(in.fist,in.second))
{
qq.push(in);
vis[in.first][in.second] = 1;
step[in.first][in.second] = step[st.first][st.second]+1;
}
}
}
return -1;
}
vector
数组在创建的时候要指定大小,vector可以理解为可以按照需要自动增长和缩短的动态数组
#include<vector> //包含头文件
vector<int> v //创建一个vector ,存放int型
vector<int> v(5) //创建vector5个元素,并系统初始化0
vector<int> v(5,3) //创建vector5个元素,并把每个元素都初始化3
/***********************/
vector<int> v;
v.reserve(5) //为v预留5个空间
strings str = "abc";
vector<char> v(str.begin(),str.end()) //v :abc
v.front() //获取第一个元素
v.back() //获取最后一个元素 14 15不能对空容器调用
/***********************/
v.push_back(11);//向vector里面放数据
v.pop_back(); //删除最后的一个元素 ,不能对空容器使用
v[0] = 1; //使用下标
v.size(); //获取实际元素的数量
v.capacity(); //获取内部数组能存放元素的最大数量 ,自动扩容
v.empty(); //判断容器是否为空 为空 返回true
vector<int>::iterator iter = v.begin();
元素的插入
vector<char> v(3,'c'); //ccc
vector<char>::iterator it =v.begin()+1;
it = v.insert(it,'d'); //cdcc 在位置it前插入d
v.insert(it,2,'a'); //caadcc 在位置it前插入2个a
string str = "abc";
v.insert(v.end(),str.begin(),str.end()); //caadccabc
//在v.end()前面插入
for(size_t i =0;i<v.size();i++)
{
cout<<v[i]<<endl;
}
迭代器
begin()
——数组首地址
end()
——最后一个元素的后一个位置 // 该位置没有元素,不能解引用
统计字符串数字个数
isdigit函数
string str;
getline(cin,str);
int cnt = 0;
//把iter理解成一个指针
for(string::iterator iter = str.begin();iter != str.end();iter++)
{
if(isdigit(*iter)) //isdigt函数,判断是否为十进制数字,可以直接用
cnt++;
}
cout<<cnt;
反转string中单词
reverse函数
string str;
getline(cin,str);
for(string::iterator first = str.begin(),it = str.begin();first!=str.end();)
{
for(;it!=str.end()&&*it!=' ';++it);
reverse(first,it);
//reverse反转[first,it)内的顺序 <algorithm>
//用于字符串/数组/容器
for(;it!=str.end()&&*it==' ';++it);
first = it;
}
cout<<str<<endl;
advance
advance(iter,3)
迭代器iter向前移动3个, 直接移动对应个数对应元素,
distance
distance(str.begin(),str.end())
- 求出两个迭代器之间的距离
- 迭代器类型一样
- 要保证first能自增到last的位置