目录
1.矩阵内部的1块
2.从1开始,+1或乘2,计算要多少次达到n
3.迷宫路径
1.矩阵内部的1块
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
const int N=130,maxn=101;
int n=2,m=2,k;
int wi[N]={1,2},C[maxn][maxn]={0},inq[maxn][maxn]={0},W[maxn][maxn];
int r[]={0,0,1,-1};
int c[]={1,-1,0,0};
int step=0;int ans=-1;int w0;
struct node
{int x,y;
}Node; // node是结构体类别名,Node是结构体的个体的名字
bool can(int x,int y)
{if(x>n || y>m ||x<0 ||y<0) {//printf("1");return false;}if(inq[x][y] || !W[x][y]) {//printf("2");printf("#%d%d#$%d%d$",x,y,inq[x][y] , !W[x][y]);return false; }return true;
}void bfs(int x,int y)
{queue<node> q;Node.x=x;Node.y=y;q.push(Node);inq[x][y]=1;while(!q.empty()){node Node2=q.front();q.pop();int X=Node2.x;int Y=Node2.y;
for(int j=0;j<4;j++){int nx=X+r[j];int ny=Y+c[j];//printf(">");if(can(nx,ny)) {Node.x=nx;Node.y=ny;q.push(Node);inq[nx][ny]=1;//printf("Test%d%dtesT",nx,ny);}}}
}int main()
{//D[0][0]=1;
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{scanf("%d",&W[i][j]);}
int ans=0;
for(int i=0;i<n;i++)
{for(int j=0;j<m;j++)
{if(can(i,j)){//printf("^");bfs(i,j);ans++;//printf("\n-%d%d-\n",i,j);}
}}
printf("%d",ans);
}
2.从1开始,+1或乘2,计算要多少次达到n
如何记录次数?我选择再开一个queue,
demo, 这个代码超时了
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
const int N=13,maxn=10;
int n=2,m=2,k;
int wi[N]={1,2},C[maxn][maxn]={0},inq[maxn][maxn]={0},W[maxn][maxn];int bfs(int n)
{int ans=0;
queue<int> q,q2;
q.push(1);q2.push(ans);while(q.front()!=n){int a=q.front();int a2=q2.front();//printf(" %d ",a);q.pop();a2++;q2.pop();q.push(a+1);q2.push(a2);q.push(a*2);q2.push(a2);}return q2.front();
}int main()
{//D[0][0]=1;
scanf("%d",&n);
//for(int i=0;i<n;i++)
//for(int j=0;j<m;j++)
//{scanf("%d",&W[i][j]);}
//int ans=0;
//for(int i=0;i<n;i++)
//{for(int j=0;j<m;j++)
//{
// if(can(i,j))
// {//printf("^");
// bfs(i,j);ans++;//printf("\n-%d%d-\n",i,j);
// }
//}
printf("%d",bfs(n));
}
改进:1.没有用一个列表记录不让他重复入队的问题 。
2.如何知道BFS深度?
我用了两个队列,或许这是超时的主要原因),答案是每次记录队列长度,遍历一个队列(同一层·时,在同一个循环里头),循环完了step++
3. //###这一步很重要 ,我之前写的是for(int i=0;i<q.size();i++),最后算出来结果不对,原因是q.size随着循环在变化,应当在循环结束时更新,而不是一边循环一边更新
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
const int N=200000,maxn=10;
int n=2,m=2,k;
//int wi[N]={1,2},C[maxn][maxn]={0},inq[maxn][maxn]={0},W[maxn][maxn];
int hs[N]={0};int bfs(int n)
{int ans=0;
queue<int> q;//,q2;
q.push(1);//q2.push(ans);
hs[1]=1;while(1){int cnt=q.size();//###这一步很重要 ,我之前写的是for(int i=0;i<q.size();i++),最后算出来结果不对,原因是q.size随着循环在变化,应当在循环结束时更新,而不是一边循环一边更新 for(int i=0;i<cnt;i++){//printf("%d ",q.front());int a=q.front();//int a2=q2.front();printf(" %d ",a);q.pop();//a2++;q2.pop();//if(a==n) return ans;if(a+1==n || a*2==n) return ans+1;//q.push(a+1);q2.push(a2);q.push(a*2);q2.push(a2);if(!hs[a+1] && a+1<=n){q.push(a+1);hs[a+1]=1;}//&&前后最好掉一下位置,否则数组要开大一点,不然数组会越界,血与泪的教训。if(!hs[a*2] && a*2<=n){q.push(a*2);hs[a*2]=1;}}ans++;}//return q2.front();
}int main()
{//D[0][0]=1;
scanf("%d",&n);
//for(int i=0;i<n;i++)
//for(int j=0;j<m;j++)
//{scanf("%d",&W[i][j]);}
//int ans=0;
//for(int i=0;i<n;i++)
//{for(int j=0;j<m;j++)
//{
// if(can(i,j))
// {//printf("^");
// bfs(i,j);ans++;//printf("\n-%d%d-\n",i,j);
// }
//}
printf("%d",bfs(n));
}
思考:如何记录最佳算法?
类似于这种pre数组,用了运筹学动态规划的思想,全局最优的话,一定局部最优,
比如 如果你是从7到的14,那么,7之前一定是按照“如何到7”的最优方法走的,最后pre数组相当于打表,记录了每一个数字前一个必经之数。
具体懒得写了,将在下一个 迷宫路径 中进行具体实现。
3.迷宫路径
见下一篇