一.1:maze 关于地图的最短路径问题
(1):问题描述:
本题输入数据为一个5*5的地图,问题是求得左上角(0,0)到右下角(5,5)的最短路径,并输出途径的地图网格,其中输入数据中0代表可以走,1代表不可以走。
(2):思路
这道题很明显可以用bfs进行解题,为了解题的简单我为地图新增了墙壁,就是在地图最外围新增一圈(1,1);也为了输出的简便,我们从终点开始向起点进行反向遍历,这样结果输出的时候直接就是正向的路径,比较省力。
#include <iostream>
#include<queue>
#include<algorithm>
#include<string.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct point
{
int x,y;
point(){
};
point(int x,int y)
{
this->x=x;
this->y=y;
};
};
queue<point> Q;
bool vis[7][7];
int a[7][7];
int sx,sy,tx,ty;
int dx[]={0,0,1,-1};
int dy[]={-1,1,0,0};
//queue<point> P;
point C[7][7];//point结构体必须有空构造
void bfs(point &A,point &B)//输入起始点 ,并记录路径,A是终点,B是起点
{
point t;
t.x=5;t.y=5;
Q.push(t);
// P.push(t);
vis[5][5]=true;
C[A.x][A.y]=A;
while(!Q.empty())
{
point now=Q.front();
Q.pop();
if(now.x==1&&now.y==1)//到起点
{
return;
}
for(int i=0;i<4;i++)
{
int x=now.x+dx[i];
int y=now.y+dy[i];//进行上下左右的移动
if(a[x][y]==0&&vis[x][y]==false)//没有到过且可以走
{
vis[x][y]=true;
point t1;
t1.x=x;t1.y=y;
Q.push(t1);
C[x][y]=now;//把现在的点输入到路径中
}
}
}
}
int main(int argc, char** argv)
{
for(int i=0;i<7;i++)
{
a[0][i]=1;
a[i][0]=1;
a[i][6]=1;
a[6][i]=1;
}//可以自己设置n,m代表地图大小进行输入
memset(vis,false,sizeof(vis));
for(int i=1;i<6;i++)
{
for(int t=1;t<6;t++)
{
cin>>a[i][t];
}
}
point begins(1,1),ends(5,5);
bfs(ends,begins);
point t(1,1);
cout<<"(0, 0)"<<endl;
while(t.x!=5||t.y!=5)
{
t=C[t.x][t.y];
cout<<'('<<t.x-1<<", "<<t.y-1<<')';
if(t.x==5&&t.y==5)
{
continue;
}
else
{
cout<<endl;
}
}
return 0;
}
一.2:pour water
(1):问题描述:
输入三个数据,前两个代表可用的两个杯子的容量,其中A与B杯互质,A<=B;第三个数据就是所求的水的容量,需要用那两个允许使用的杯子进行目标的求解,其实这也是个地图的问题,更确切地说是隐式图
(2):思路 这道题的思路和平时代的bfs基本一致只不过状态多了一些,有六个fill A,fill B,pour A B,pour B A,empty A,empty B。
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<string.h>
using namespace std;
struct status
{
int a,b;
bool operator<(const status &s)const
{
return a!=s.a?a<s.a:b<s.b;
}
};
int AA[1005][2],a1=0;
void print(status &p,map<status,status> & from)
{
if(from.find(p)==from.end()||(p.a==0&&p.b==0))
{
return;
}
print(from[p],from);
AA[a1][0]=p.a;
AA[a1][1]=p.b;
a1++;
}
void refresh(status &s,status &t,map<status,status> &from,queue<status> &Q)//判断是否能加入
{
if(from.find(t)==from.end())
{
from[t]=s;
Q.push(t);
}
}
void bfs(int A,int B,int C)
{
queue<status> Q;
map<status,status>from;
status s,t;
s.a=0;s.b=0;
Q.push(s);
while(!Q.empty())
{
s=Q.front();
Q.pop();
if(s.a==C||s.b==C)
{
print(s,from);
for(int i=0;i<a1;i++)//通过判断当前点与前一个点的关系来判断输出的内容
{
if(i==0)
{
if(AA[0][0]==0)
{
cout<<"fill B"<<endl;
}
if(AA[0][1]==0)
{
cout<<"fill A"<<endl;
}
}
else
{
if((AA[i][0]+AA[i][1])==(AA[i-1][0]+AA[i-1][1]))
{
if(AA[i][0]>AA[i-1][0])
{
cout<<"pour B A"<<endl;
}
if(AA[i][1]>AA[i-1][1])
{
cout<<"pour A B"<<endl;
}
}
else
{
if(AA[i][0]>AA[i-1][0])
{
cout<<"fill A"<<endl;
}
if(AA[i][1]>AA[i-1][1])
{
cout<<"fill B"<<endl;
}
if(AA[i][0]!=0&&AA[i][0]==AA[i-1][0]&&AA[i][1]==0)
{
cout<<"empty B"<<endl;
}
if(AA[i][1]!=0&&AA[i][1]==AA[i-1][1]&&AA[i][0]==0)
{
cout<<"empty A"<<endl;
}
}
}
}
a1=0;
memset(AA,0,sizeof(AA));
cout<<"success"<<endl;
return;
}
if(s.a>0)
{
t.a=0;
t.b=s.b;
refresh(s,t,from,Q);
}
if(s.b>0)
{
t.b=0;
t.a=s.a;
refresh(s,t,from,Q);
}
if(s.a<A)
{
t.a=A;
t.b=s.b;
refresh(s,t,from,Q);
if(s.b!=0)
{
if(s.a+s.b<=A)
{
t.a=s.a+s.b;
t.b=0;
refresh(s,t,from,Q);
}
else
{
t.a=A;
t.b=s.a+s.b-A;
refresh(s,t,from,Q);
}
}
}
if(s.b<B)
{
t.a=s.a;
t.b=B;
refresh(s,t,from,Q);
if(s.a!=0)
{
if(s.a+s.b<=B)
{
t.a=0;
t.b=s.a+s.b;
refresh(s,t,from,Q);
}
else
{
t.a=s.a+s.b-B;
t.b=B;
refresh(s,t,from,Q);
}
}
}
}
cout<<"-1"<<endl;
}
int main()
{
int a,b,c;
while(cin>>a&&a!=EOF)
{
cin>>b>>c;
bfs(a,b,c);
}
return 0;
}