一.搜索
1.广度优先搜索(BFS)
有时候需要解决连通性,最短问题时,可以考虑使用广度优先搜索。
广度优先搜索会优先考虑每种状态和初始状态的距离,与初始状态越接近的情况就会越先考虑。
过程:先将初始状态加入到空的队列中 ,然后每次取出队首,找出队首所能转移到的状态,再将其压入队列,如此反复,直到队列为空。
形式如下:
Q.push(初始状态);//将初始状态入列
while(!Q.empty()){
State u =Q.front(); //取出队首
Q.pop();//出队
for(枚举所有可扩展状态) //找到u的所有可达 状态v
if(是合法的)//v需要满足某些条件,如未 访问过,未在队内等
Q.push(v);//入队
}
2.深度优先搜索(DFS)
从初始状态,利用规则生成搜索树下一层任一个结点,检查是否出现目标状态,若未出现,以此状态利用规则生成再下一层任一个结点,再检查,重复过程一直到叶节点(即不能再生成新状态节点),当它仍不是目标状态时,回溯到上一层结果,取另一可能扩展搜索的分支。采用相同办法一直进行下去,直到找到目标状态为止。
具体实现过程:
1 .每次取出栈顶元素,对其进行拓展。
2. 若栈顶元素无法继续拓展,则将其从栈中弹出。继续1过程。
3 .不断重复直到获得目标状态(取得可行解)
或栈为空(无解)。
二.高精度运算
每种数据类型能够容纳的数字范围是有限的。一般情况下使用 int 类型,如果数字大一点还能使用 long long 类型。如果需要存储或者使用更大的整数该怎么办呢?不能使用浮点数,因为浮点数的有效数宇位数也是有限的。有些编译器允许提供_int128 类型,但是不仅大小依然局限(最多可以表示接近 40位的十进制数),而且使用范围也很局限。不过,可以使用数组来模拟非常长的整数。
分析:用数组来模拟非常长的整数,这意味着可以用数组的每一位记录那个数字上的每一位。也就是说,可以用n位数组来记录一个几位数字。
分别在两行内输入两个500位以内的十进制非负整数,求他们的和,代码如下:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
#define maxn 520
int a[maxn],b[maxn],c[maxn];//用数组来模拟非常长的整数
int main()
{
string A,B;
cin>>A>>B;//输入两个整数
int len=max(A.length(),B.length());
for(int i=A.length()-1,j=1;i>=0;i--,j++)
a[j]=A[i]-'0';
for(int i=B.length()-1,j=1;i>=0;i--,j++)
b[j]=B[i]-'0';//用n位数组来记录一个n位数字
for(int i=1;i<=len;i++)
{
c[i]+=a[i]+b[i];
c[i+1]=c[i]/10;//模拟进位
c[i]%=10;
}
if(c[len+1])//最后进位可能会导致位数增加
len++;
for(int i=len;i>=1;i--)
cout<<c[i];
return 0;
}
三.algorithm头文件下的函数(sort)
sort是用来排序的函数,它根据具体情形使用不同的排序方法。
1.如何使用sort排序
sort函数的使用必须加上头文件#include<algorithm>,
使用方法如下:
sort(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填));
可以看到,sort的参数有三个,其中前两个是必填的,而比较函数则可以根据需要填写,
如果不写比较函数,则默认对前面给出的区间进行递增排序。
int a[6]={9,4,2,5,6,-1}
sort(a,a+6);//将a[0]~a[5]从小到大排序
for(int i=0;i<6;i++)
cout<<a[i]<<" ";
输出结果:-1 2 4 5 6 9
对char型数组排序(默认为字典序):
char c[]={'T','W','A','K'};
sort(c,c+4);
for(int i=0;i<4;i++)
cout<<c[i];
输出结果:AKTW
sort的第三个可选参数就是compare函数(一般写作cmp函数)。
如果想要从大到小来排序,则要使用比较函数cmp来“告诉”sort何时要交换元素,可以这样写:
bool cmp(int a,int b)
return a>b;//可以理解为当a>b时把a放在b前面
int a[]={3,1,4,2};
sort(a,a+4,cmp);
for(int i=0;i<4;i++)
cout<<a[i]<<" ";
输出结果:4 3 2 1
对char型数组从大到小排序:
bool cmp(char a,char b)
return a>b;
int main()
{char c[]={'T','W','A','K'};
sort(c,c+4,cmp);
for(int i=0;i<4;i++)
cout<<c[i];
}
输出结果:WTKA
记忆方法:如果要把数据从小到大排序,那么就用"<",因为”a<b“就是左小右大;如果要把数据从大到小排序,
那么就用”>“。
(2)结构体数组的排序
现定义了如下的结构体:
struct node{int x,y;
}ssd[10];
如果想让ssd数组按照从小到大排序(即进行一级排序),那么可以这样写cmp函数:
bool cmp(node a,node b)
return a.x>b.x;//按x值从大到小对结构体数组排序
ssd[0].x=2;
ssd[0].y=2;
ssd[1].x=1;
ssd[1].y=3;
ssd[2].x=3;
ssd[2].y=1;
sort(ssd,ssd+3,cmp);//排序
for(int i=0;i<3;i++)
cout<<ssd[i].x<<" "<<ssd[i].y<<endl;
输出结果:3 1
2 2
1 3
而如果想先按x从大到小排序,但当x相等的情况下,按照y的大小从小到大来排序(即进行二级排序),那么cmp的写法是:
bool cmp(node a,node b)
if(a.x!=b.x) return a.x>b.x;
else return a.y<b.y;
这里的cmp函数首先判断结构体内的x元素是否相等,如果不相等,则直接按照x的大小来排序;否则,比较两个结构体中y
的大小,并按y从小到大排序。
(3)容器的排序
在STL标准容器中,只有vector、string、deque是可以使用sort的。这是因为像set、map这种容器是用红黑树实现的,元素本身有序,故不允许使用sort排序。