Garrison
2019-08-20 21:53:58
这道题有这么多人发题解啊,我也来凑一凑热闹。
很明显,一个普通的BFS
int x,y,z;
scanf("%d%d",&n,&ge);
for(int i=1;i<=ge;++i){
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z+1;
}
这一段是输入,储存他们的颜色,在这里,我将两种颜色分别用1、2表示(为了方便将没图色的用0来表示),所以颜色的地方+1。a数组存的是地图上哪里的颜色是什么样的。
struct edge{
int xx,yy,money,color;
bool use;
friend bool operator <(const edge &xxx,const edge &yyy){
return xxx.money>yyy.money;
}
};
对于我这种蒟蒻来说,BFS就离不开结构体。xx、yy:表示位置,money:在这一个点用了多少钱,color:所在点颜色,use这个点的有没有放过魔法(0及没有,1及有)
结构体中最重要的就是operator重载运算符了,需注意它的用法(实测无误)
void BFS(){
priority_queue<edge> Q;//优先队列
edge e;
//第一个点初始化
e.xx=e.yy=1,e.money=e.use=0;
e.color=a[1][1];
Q.push(e);
b[1][1]=1;
while(!Q.empty()){
edge t;
t=Q.top();Q.pop();
for(int i=0;i<4;++i){//四个方向
edge news;
news.xx=t.xx+wx[i],news.yy=t.yy+wy[i];
if(news.xx<1||news.yy<1||news.xx>n||news.yy>n||b[news.xx][news.yy])
continue;
news.use=!t.use;//上一格没用则这一格用,上一格用魔法则这一格不用
if(a[news.xx][news.yy]==0){//看一下这一个是不是没有颜色
//如果没有颜色
if(news.use)//如果这一格用魔法
news.money=t.money+2,news.color=t.color,news.use=1;
else continue;//不能用魔法,跳过。
}
else{
//有颜色
if(news.use)
news.use=0;//如果这一格要用魔法,则没必要用(反正有颜色了)
if(a[news.xx][news.yy]==t.color)//颜色相同不要钱
news.money=t.money,news.color=a[news.xx][news.yy];
else//不相同要钱
news.money=t.money+1,news.color=a[news.xx][news.yy];
}
b[news.xx][news.yy]=1;//走过了不能走
if(news.xx==n&&news.yy==n){//到达
printf("%d\n",news.money);
return;
}
Q.push(news);//入队
}
}
printf("-1\n");
}
这一段代码就是核心部分,四个方向分别走,b数组存有没有到过。(其它我已p了注释,请诸位dalao自行审阅)
#include<bits/stdc++.h>
using namespace std;
#define N 105
int a[N][N],n,ge;
const int wx[5]={0,0,1,-1};
const int wy[5]={1,-1,0,0};
bool b[N][N];
struct edge{
int xx,yy,money,color;
bool use;
friend bool operator <(const edge &xxx,const edge &yyy){
return xxx.money>yyy.money;
}
};
void BFS(){
priority_queue<edge> Q;
edge e;
e.xx=e.yy=1,e.money=e.use=0;
e.color=a[1][1];
Q.push(e);
b[1][1]=1;
while(!Q.empty()){
edge t;
t=Q.top();Q.pop();
for(int i=0;i<4;++i){
edge news;
news.xx=t.xx+wx[i],news.yy=t.yy+wy[i];
if(news.xx<1||news.yy<1||news.xx>n||news.yy>n||b[news.xx][news.yy])
continue;
news.use=!t.use;
if(a[news.xx][news.yy]==0){
if(news.use)
news.money=t.money+2,news.color=t.color,news.use=1;
else continue;
}
else{
if(news.use)
news.use=0;
if(a[news.xx][news.yy]==t.color)
news.money=t.money,news.color=a[news.xx][news.yy];
else
news.money=t.money+1,news.color=a[news.xx][news.yy];
}
b[news.xx][news.yy]=1;
if(news.xx==n&&news.yy==n){
printf("%d\n",news.money);
return;
}
Q.push(news);
}
}
printf("-1\n");
}
int main(){
int x,y,z;
scanf("%d%d",&n,&ge);
for(int i=1;i<=ge;++i){
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z+1;
}
BFS();
return 0;
}
但是这样就真的可以了吗?如果你和上面的程序几乎一样,你就只有95分。
为什么?因为漏了起点是重点的情况,所以要加上一段:
if(n==1){
printf("0\n");
return 0;
}
谢谢