双向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 }//快速幂
浙公网安备 33010602011771号