双向bfs,指从初始和结果两端进行广搜,要求结果已定,而不是符合特定的条件

一般开两个队列,用不同的值标记vis,遇到时则表示找到结果

下面的是经典的走迷宫双向bfs

 1 int n,m;
 2 int vis[10][10];
 3 int step[10][10];
 4 char arr[10][10];
 5 int ans=0;
 6 int fx[4]={0,-1,0,1};
 7 int fy[4]={1,0,-1,0};
 8 void dbfs(){
 9     queue<pair<int,int>>q1;
10     queue<pair<int,int>>q2;
11     q1.push(make_pair(1,1));
12     step[1][1]=1;
13     step[n][m]=1;
14     vis[1][1]=1;
15     vis[n][m]=2;
16     q2.push(make_pair(n,m));
17     while(!q1.empty()&&!q2.empty()){
18         int flag;
19         int x,y;
20         if(q1.size()>q2.size()){
21             x=q1.front().first;
22             y=q1.front().second;
23             q1.pop();
24             flag=1;
25         }else{
26             x=q2.front().first;
27             y=q2.front().second;
28             q2.pop();
29             flag=2;
30         }
31         for(int i=0;i<4;++i){
32             int cx=x+fx[i];
33             int cy=y+fy[i];
34             if(cx>=1&&cx<=n&&cy>=1&&cy<=m&&arr[cx][cy]!='1'){
35                 if(!step[cx][cy]){
36                     vis[cx][cy]=vis[x][y];
37                     step[cx][cy]=step[x][y]+1;
38                     if(flag==1){
39                         q1.push(mp(cx,cy));
40                     }else
41                         q2.push(mp(cx,cy));
42                 }else if(vis[cx][cy]+vis[x][y]==3){
43                     ans=step[cx][cy]+step[x][y]-1;
44                 }
45             }
46         }
47     }
48 }//双向bfs 
49 int main(){
50     cin>>n>>m;
51     for(int i=1;i<=n;++i){
52         for(int j=1;j<=m;++j){
53             cin>>arr[i][j];
54         }
55     }
56     dbfs();
57     cout<<ans<<endl;
58     return 0;
59 } 

二分指答案在某个区间上单调,例如在某个点往左成立,往右不成立,可以二分求出这个点

应用题目,答案单调,求最大的最小或最小的最大

难点是写judge判断函数

 1 int ans(int l, int r)
 2 {
 3     int ans = 0;
 4     while (l <= r)
 5     {
 6         int mid = (r + l) / 2;
 7         if (judge(mid)) {
 8             l = mid + 1;//根据答案的单调性自行对左右进行更改
 9             ans = mid;
10         }
11         else
12             r = mid - 1;
13     }
14     return ans;
15 }//二分模板;注意二分什么,即judge传入的值是什么。

两端点二分,只在一个区间上成立,求区间的点

答案还是单调,只不过过大或过小导致不成立,根据过大或过小更改左右进行两次二分就行

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

贪心一般代码量比较小,难的是如何贪心,当推不出来时,可以假设贪心,对案例进行运算,结果不同则说明贪心的方向错了

 

 

 

 

分治是将问题拆分,一般是对半分跑递归,再整合向上返回

如归并排序,将数组分半,那么我们就能拿到两个排好序的数组,然后再对两个数组进行排序就行了

 1 void msort(int l,int r){
 2     if(l==r){
 3         return;
 4     }
 5     int mid=(l+r)/2;
 6     msort(l,mid);
 7     msort(mid+1,r);
 8     int i=l;
 9     int j=mid+1;
10     int k=i;
11     while(i<=mid&&j<=r){
12         if(arr[i]<arr[j]){
13             c[k++]=arr[i++];
14         }else{
15             c[k++]=arr[j++];
16         }
17     }
18     while(i<=mid){
19         c[k++]=arr[i++];
20     }
21     while(j<=r){
22         c[k++]=arr[j++];
23     }
24     for(int x=l;x<=r;++x){
25         arr[x]=c[x];
26     }
27 }//归并排序
 1 int quickPower(int a, int b)//是求a的b次方
 2 {
 3     int ans = 1, base = a;//ans为答案,base为a^(2^n)
 4     while (b > 0)//b是一个变化的二进制数,如果还没有用完
 5     {
 6         if (b & 1)//&是位运算,b&1表示b在二进制下最后一位是不是1,如果是:
 7             ans *= base;//把ans乘上对应的a^(2^n)
 8 
 9         base *= base;//base自乘,由a^(2^n)变成a^(2^(n+1))
10         b >>= 1;//位运算,b右移一位,如101变成10(把最右边的1移掉了),10010变成1001。现在b在二进制下最后一位是刚刚的倒数第二位。结合上面b & 1食用更佳
11     }
12     return ans;
13 }//快速幂