没想到这么久没写博客了!之前蓝桥杯省赛加校赛一直没空补博客内容....(打水漂真的挺好玩的)
最近开始补kuangbin专题,虽然是简单搜索。。。但是做着一点都不简单= =
POJ - 1321
第一题,大意是说给个棋盘(矩形),有可放棋子的地方和不可放棋子的地方,给定需要放的棋子数,且一行或一列只允许有一个棋子,求一共的方案数。Ps:我只知道这数据特别小....写个dfs就过去了,不过我的dfs真的弱啊。。
#include
#include
#include
using namespace std;
int map[8+5][8+5];
int vis[8+5];
int k,n; //k是放的棋子数,n是棋盘大小
int cnt;
void dfs(int x,int num)
{
if(num==k)
{
cnt++;
return ;
}
if(x>n) return ;
for(int i=1;i<=n;i++)
{
if(vis[i]==0&&map[x][i]==1)
{
vis[i]=1;
dfs(x+1,num+1);
vis[i]=0;
}
}
dfs(x+1,num);
}
int main()
{
char ch;
while(scanf("%d%d",&n,&k)&&n!=-1&&k!=-1) //限制条件
{
if(n==-1&&k==-1)
break;
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
cnt=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>ch;
if(ch=='#')
map[i][j]=1;
else
map[i][j]=0;
}
/*for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<
POJ - 2251
题目大意:一个类似塔的迷宫,每一个格子可以跳上一层或者落下一层,以及上下左右,找出最少时间。
这题让我注意到了bfs和dfs分别该怎么用,对于迷宫,一般dfs都是求可不可以到达,bfs求的是到达的步数吧(慢慢从起点上下左右的走)。(可能有错,个人理解)
BFS能够求得最短路径,因为BFS每进行一次相当于当前的路径长度。对于一个N*N矩阵,BFS最多运行n*n次。
深度优先搜索优先寻找离起点最远的顶点,广度优先搜索最先找最近的顶点 ,
深度优先找到的必然是一个连通分量(因为走到死胡同为止)。-----引用一位大佬的话...
#include
#include
#include
#include
using namespace std;
int l,r,c;
char map[30+5][30+5][30+5]; //x,y,z
int vis[30+5][30+5][30+5];
int s[6][3]={{0,0,-1},{0,0,1},{0,-1,0},{0,1,0},{1,0,0},{-1,0,0}}; //上下左右前后x,y,z
struct node
{
int x,y,z;
int step;
};
int sx,sy,sz; //记录起点位置
void init() //初始化
{
memset(vis,0,sizeof(vis));
memset(map,0,sizeof(map));
}
void pin(queue q) //打印队列。。。我测试用
{
node a;
cout<<"now"< q;
node a,stem;
a.x=sx;
a.y=sy;
a.z=sz;
a.step=0;
q.push(a);
vis[sx][sy][sz]=1;
while(!q.empty())
{
//pin(q);
a=q.front(); //取队头
if(map[a.x][a.y][a.z]=='E')
{
cout<<"Escaped in "<r||a.x+s[i][0]<1||a.y+s[i][1]>c||a.y+s[i][1]<1||a.z+s[i][2]>l||a.z+s[i][2]<1)
continue; //边界判断!!!
if(!vis[a.x+s[i][0]][a.y+s[i][1]][a.z+s[i][2]]&&map[a.x+s[i][0]][a.y+s[i][1]][a.z+s[i][2]]!='#') //若未访问且不是障碍
{
stem.x=a.x+s[i][0];
stem.y=a.y+s[i][1];
stem.z=a.z+s[i][2];
stem.step=a.step+1;
vis[a.x+s[i][0]][a.y+s[i][1]][a.z+s[i][2]]=1;
q.push(stem);
}
}
}
cout<<"Trapped!"<>l>>r>>c&&l+r+c!=0)
{
init();
for(int k=1;k<=l;k++)
{
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
cin>>map[i][j][k];
if(map[i][j][k]=='S')
sx=i,sy=j,sz=k;
}
}
}
BFS();
}
}
C - Catch That Cow
题目大意:一个牛在一个直线上,而放牛人可以走三种①x+1②x-1③x*2,问最短走到的步数(这题在我最开始接触acm的时候做到过。。。觉得这题这恶心,现在看起来好简单啊= =)不过我做的时候还是很慢。。
#include
//数组只能开到1e11 int c[100000*2+5]; int wz[100000*2+5]; int n,k; int ans; int now,to; //now代表前一个集合数,to是计算根据前一个集合入队的新集合数 /*void bfs(int v) //5 17为例 {5}{6,4,10}{7,12,3,8,9,11,20}....一个集合入队为加一分钟时间(我的弱算法,太长了!) { queue#include #include #include using namespace std; bool vis[100000*2+5]; //数组只能开到1e11 int c[100000*2+5]; int wz[100000*2+5]; int n,k; int ans; int now,to; //now代表前一个集合数,to是计算根据前一个集合入队的新集合数 /*void bfs(int v) //5 17为例 {5}{6,4,10}{7,12,3,8,9,11,20}....一个集合入队为加一分钟时间(我的弱算法,太长了!) { queue q; //创建队列 q.push(v); //将起点入队,作为队头 vis[v]=true; //入队的标记 int num=1,to; while(!q.empty()) //遍历队列q { ans++; for(int i=1;i<=num;i++) { c[i]=q.front(); //取队头 q.pop(); if(c[i]==k) { cout< q; //创建队列 q.push(v); //将起点入队,作为队头 wz[v]=0; //入队的标记 while(!q.empty()) //遍历队列q { int x=q.front(); //取队头 q.pop(); if(x==k) { cout< >n>>k) { ans=-1; bfs_better(n); } return 0; } q; //创建队列 q.push(v); //将起点入队,作为队头 vis[v]=true; //入队的标记 int num=1,to; while(!q.empty()) //遍历队列q { ans++; for(int i=1;i<=num;i++) { c[i]=q.front(); //取队头 q.pop(); if(c[i]==k) { cout< q; //创建队列 q.push(v); //将起点入队,作为队头 wz[v]=0; //入队的标记 while(!q.empty()) //遍历队列q { int x=q.front(); //取队头 q.pop(); if(x==k) { cout< >n>>k) { ans=-1; bfs_better(n); } return 0; }
POJ - 3279
题目大意:奶牛要翻砖块,黑色和白色,需要全白。给了一个矩阵,1代表黑色,0代表白色,问最少翻转次数,并且用矩阵表示出来。。这个题面也是没谁了。(这题感觉和POJ1753很像。。不过做法都不一样,明早醒来再看看具体为什么)
做法:枚举第一行的情况(得到了一种枚举二进制的方法),然后从第二行开始,因为每个棋子都看作翻转全靠下面那块地方,然后每个都这样试完到最后看一看最后一行是否全白即可。
#include //自写
#include
#include
using namespace std;
int map[15+5][15+5]; //初始化棋盘
int cal[15+5][15+5]; //翻转次数的棋盘
int ans[15+5][15+5]; //最后存储的棋盘
int n,m;
int minnum=15*15+5,num; //minnum为最少翻转次数,num为翻转次数
int p[5][2]={{0,0},{-1,0},{0,1},{1,0},{0,-1}};//原,上,右,下,左
bool check(int x,int y) //白色返回true
{
int a=map[x][y];
for(int i=0;i<5;i++)
{
a+=cal[x+p[i][0]][y+p[i][1]];
}
if(a%2==0)
return true;
else return false;
}
void dfs(int x)
{
num=x;
for(int i=2;i<=n;i++)//从第二行开始往下检查,若当前检查的上一块是黑的则需要翻转
{
for(int j=1;j<=m;j++)
if(check(i-1,j)==false)
{
cal[i][j]=1;
num++;
}
}
for(int i=1;i<=m;i++)
{
if(check(n,i)==false) //有黑色 则不行
return ;
}
if(num>n>>m)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>map[i][j];
}
int end=1<>j)&1;
if(cal[1][m-j])
x++;
}
dfs(x);
}
if(minnum==15*15+5)
cout<<"IMPOSSIBLE"<
POJ - 1426
题目大意:给一个数n,输出一个n的倍数,且用1010表示(但是还是十进制,并不是二进制)
最开始没思路。。。忍不住看了网上的发现也太简单了。。以后决定忍住不看答案先想想.
值得一提的这里需要unsigned long long
llu是1e19,而ll是1e18,int是1e9
#include
using namespace std;
bool flag;
void dfs(unsigned long long num,int n,int k) //num是当前数,n是输入的数,k是位数
{
if(flag)
return;
if(num%n==0)
{
printf("%llu\n",num);
flag=true;
return;
}
if(k==19)
return;
dfs(num*10,n,k+1);
dfs(num*10+1,n,k+1);
}
int main()
{
int n;
while(cin>>n,n)
{
flag=false;
dfs(1,n,0);
}
return 0;
}
G - Shuffle'm Up
题目大意:
按如图所示的方式将两个牌堆合在一起,求合几次能得到与题目要求相同的牌堆,若永远无法得到,输出-1
思路:模拟,若模拟次数大于2*C,则永远得不到要求的牌堆
直接给代码模拟
#include
#include
using namespace std;
string a,b,ans,temp1,temp2,fir;
int main()
{
int n,m,flag,k;
cin>>n;
for(int i=1;i<=n;i++)
{
flag=0;
k=0;
cin>>m;
cin>>a>>b>>ans;
fir=a+b;
temp2=a+b;
temp1=a+b;
while(1)
{
k++;
for(int j=0;j2*m||temp1==fir)
break;
}
if(flag)
cout< int n,m,flag,k;
cin>>n;
for(int i=1;i<=n;i++)
{
flag=0;
k=0;
cin>>m;
cin>>a>>b>>ans;
fir=a+b;
temp2=a+b;
temp1=a+b;
while(1)
{
k++;
for(int j=0;j2*m||temp1==fir)
break;
}
if(flag)
cout<
H - Pots
POJ - 3414
题目大意:输入两个容器的容量A,B,一开始让两个容器为空,然后给你对这两个容器的6种操作, 让你用这6种操作最终使得A或B容器里的水最终达到C,让你输出需要倒水的次数,以及从一开始到后来得到结果的路径。(要求C的大小在A和B之间)。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 105;
const double eps = 1e-7;
bool vis[maxn][maxn];
const int dir[4][2]= {1, 0, 0, 1, -1, 0, 0, -1};
char map[maxn][maxn];
int a, b, k;
struct node
{
int vola, volb, step;
char str[maxn][maxn];
};
bool bfs()
{
memset(vis, false, sizeof(vis));
queue que;
node p, q;
p.vola = 0, p.volb = 0, p.step = 0;
que.push(p);
vis[0][0] = 1;
///vis[p.vola][p.volb] = true;
while(!que.empty())
{
p = que.front();
que.pop();
if(p.vola==k || p.volb == k)
{
cout< b
if(p.volb < b)
{
q = p;
if(q.volb + q.vola <= b)
{
q.volb += q.vola;
q.vola = 0;
}
else
{
q.vola = (q.vola+q.volb)-b;
q.volb = b;
}
q.step++;
strcpy(q.str[q.step], "POUR(1,2)");
if(!vis[q.vola][q.volb])
{
vis[q.vola][q.volb] = true;
que.push(q);
}
}
}
///把 b 倒满
if(p.volb == 0)
{
q = p;
q.volb = b;
q.step++;
strcpy(q.str[q.step], "FILL(2)");
if(!vis[q.vola][q.volb])
{
vis[q.vola][q.volb] = true;
que.push(q);
}
}
///把 b 中的水倒出来
else if(p.volb <= b)
{
q = p;
q.volb = 0;
q.step++;
strcpy(q.str[q.step],"DROP(2)");
if(!vis[q.vola][q.volb])
{
vis[q.vola][q.volb] = true;
que.push(q);
}
if(p.vola < a)
{
q = p;
if(q.vola + q.volb <= a)
{
q.vola += q.volb;
q.volb = 0;
}
else
{
q.volb = (q.vola+q.volb)-a;
q.vola = a;
}
q.step++;
strcpy(q.str[q.step], "POUR(2,1)");
if(!vis[q.vola][q.volb])
{
vis[q.vola][q.volb] = true;
que.push(q);
}
}
}
}
return false;
}
int main()
{
while(cin>>a>>b>>k)
{
bool ok = bfs();
if(!ok)
puts("impossible");
}
return 0;
}
I - Fire Game
FZU - 2150
题目大意:给一片n*m(n<10,m<=10)草地的图,‘.’代表土地,‘#’代表草丛,最开始可以点燃两个草丛,点燃的草没过一秒,火势便会往上下左右蔓延,问找出一种点燃初始草,使得时间最少将所有草丛烧完,若没办法烧完则输出-1.
思路:因为n和m都很小,我们可以枚举任意两个草进行BFS,找出时间最少的。
#include
#include
#include
const int maxn=1e6;
using namespace std;
int n,m;
int ans;
char map[10+5][10+5];
int mp[10+5][10+5];
int st[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; //上,下,右,左
struct node
{
int x,y;
int t;
};
bool check() //检查是不是所有草丛都烧完了
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(mp[i][j]==0&&map[i][j]=='#')
return false;
}
return true;
}
void bfs(node s1,node s2) //bfs
{
node n1,temp;
int tt=0; //记录进行到第几秒了
queue q;
q.push(s1);
q.push(s2);
mp[s1.x][s1.y]=1;
mp[s2.x][s2.y]=1;
while(!q.empty())
{
n1=q.front();
q.pop();
int x1=n1.x;
int y1=n1.y;
int t1=n1.t;
if(check())
{
if(tt=tt)
tt=t1+1;
if(temp.x>=1&&temp.x<=n&&temp.y>=1&&temp.y<=m&&map[temp.x][temp.y]=='#'&&!mp[temp.x][temp.y])
{
q.push(temp);
mp[temp.x][temp.y]=1;
}
}
}
return ;
}
int main()
{
node s1,s2;
int c;
cin>>c;
int num;
for(int i1=1;i1<=c;i1++)
{
num=0;
cin>>n>>m;
for(int i=1;i<=n;i++) //输入草地
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='#')
num++;
}
}
ans=maxn;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]=='#')
{
for(int k=i;k<=n;k++)
{
for(int l=1;l<=m;l++)
{
if(map[k][l]=='#')
{
if(k==i&&l<=j)
{
continue;
}
else
{
s1.x=i,s1.y=j,s1.t=0;
s2.x=k,s2.y=l,s2.t=0;
memset(mp,0,sizeof(mp));
bfs(s1,s2);
}
}
}
}
}
}
}
cout<<"Case "<
J - Fire!
UVA - 11624
题目大意:给一个地图,一个地方是火一个地方是人,火会往四个方向蔓延,看人能否找到一条最短路且不被火烧的的情况先逃生到地图外。
思路:直接先把F(火)bfs,记录火到每一格的时间,然后人在bfs看看能不能在火未到的情况下逃生。双端BFS
#include
#include
#include
using namespace std;
int n,m;
char map[1000+5][1000+5];
int mp[1000+5][1000+5]; //火势蔓延的时间
int vis_man [1000+5][1000+5];
int st[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct node
{
int x,y,step;
};
queue q;
void clear_q()//用来清除队列中的数据
{
while(!q.empty())
q.pop();
}
void bfs1(node f) //火势蔓延到每格的时间
{
//cout<<"text1"<=1&&temp.x<=n&&temp.y>=1&&temp.y<=m) //如果不是墙且等于0,即火还未蔓延到
{
cout<=1&&temp.x<=n&&temp.y>=1&&temp.y<=m&&vis_man[temp.x][temp.y]==0) //如果是.且时间小于,即火还未蔓延到
{
vis_man[temp.x][temp.y]=1;
q.push(temp);
}
}
}
cout<<"IMPOSSIBLE"<>t;
while(t--)
{
memset(mp,0,sizeof(mp));
memset(vis_man,0,sizeof(vis_man));
clear_q();
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='J')
{
j1.x=i;
j1.y=j;
j1.step=0;
}
if(map[i][j]=='F')
{
f1.x=i;
f1.y=j;
f1.step=0;
q.push(f1);
}
}
}
bfs1(f1);
/* for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<
K - 迷宫问题
POJ - 3984
题目大意:给一个矩阵,0代表路,1代表障碍,找出一条最短路,输出这条路
思路:基础bfs,pre数组记录每个点的前一个点,用来记录路径
#include
#include
using namespace std;
int map[5+5][5+5];
int mp[5+5][5+5];
int st[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int road[25+5][2];
int pre[10][10];
struct node
{
int x,y;
int prex,prey;
};
void bfs()
{
node star;
star.x=0;
star.y=0;
queueq;
q.push(star);
while(!q.empty())
{
node fi=q.front();
q.pop();
int x=fi.x;
int y=fi.y;
if(x==4&&y==4)
{
int i=1;
while(x*10+y!=0)
{
road[i][0]=x;
road[i][1]=y;
x=pre[road[i][0]][road[i][1]]/10;
y=pre[road[i][0]][road[i][1]]%10;
i++;
}
road[i][0]=x;
road[i][1]=y;
for(int k=i;k>=1;k--)
{
cout<<"("<=0&&t.x<5&&t.y>=0&&t.y<5&&mp[t.x][t.y]==0&&map[t.x][t.y]==0)
{
pre[t.x][t.y]=x*10+y;
mp[t.x][t.y]=1;
q.push(t);
}
}
}
}
void dfs(int x,int y)
{
}
int main()
{
mp[1][1]=1;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>map[i][j];
}
bfs();
return 0;
}
L - Oil Deposits
HDU - 1241
题目大意:给一个地图#代表路,@代表油,如果油的九宫格还有其他油,这些油属于同一种油,问一一共有几种油
思路:遇到@就BFS,标记与@相同的油,看看一共进行了几次bfs,一次则代表有一种油
#include
#include
#include
using namespace std;
int vis[100+5][100+5];
char map[100+5][100+5];
int ans,n,m;
struct node
{
int x,y;
};
int st[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
void bfs(int i,int j)
{
ans++;
queue q;
node t,temp;
int a,b;
t.x=i;
t.y=j;
vis[i][j]=1;
q.push(t);
while(!q.empty())
{
t=q.front();
a=t.x;
b=t.y;
q.pop();
for(int i=0;i<8;i++)
{
temp.x=a+st[i][0];
temp.y=b+st[i][1];
if(temp.x<=n&&temp.x>=1&&temp.y<=m&&temp.y>=1&&vis[temp.x][temp.y]==0&&map[temp.x][temp.y]=='@')
{
vis[temp.x][temp.y]=1;
q.push(temp);
}
}
}
return ;
}
int main()
{
while(cin>>n>>m&&(n+m)!=0)
{
memset(vis,0,sizeof(vis));
memset(map,0,sizeof(map));
ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(map[i][j]=='@'&&vis[i][j]==0)
bfs(i,j);
}
cout<
M - 非常可乐
HDU - 1495
题意:有一瓶可乐,两个空瓶子,问最少几次可以倒成2瓶一样的
思路,bfs(1->2,1->3,2->1,2->3,3->1,3->2)直到有两个瓶子是一样的,坑点是。。可乐瓶居然也可以当杯子(可能是我脑残= =)
#include
#include
#include
using namespace std;
int s,n,m;
int vis[100+5][100+5];
int pre[100+5][100+5];
struct node
{
int ls,ln,lm,step; //,s,n,m代表是三个属性,ln代表已经倒的,lm代表已经倒的
};
void bfs()
{
node t,temp;
queue q;
t.ls=s;
t.ln=0;
t.lm=0;
t.step=0;
vis[0][0]=1;
q.push(t);
int i=0;
int ls,ln,lm,step;
while(!q.empty())
{
temp=q.front();
q.pop();
ls=temp.ls;
ln=temp.ln;
lm=temp.lm;
step=temp.step;
if((ls==s/2&&lm==s/2)||(ls==s/2&&ln==s/2)||(ln==s/2&&lm==s/2))
{
/*for(int k=0;k<=5;k++)
{
for(int l=0;l<=5;l++)
{
cout<0)//将1倒给其它两瓶
{
if(ln2
{
if((ls+ln)<=n)
{
t.ls=0;
t.ln=ls+ln;
t.step=step+1;
t.lm=lm;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
else
{
t.ls=ls-(n-ln);
t.ln=n;
t.step=step+1;
t.lm=lm;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
}
if(lm3
{
if((ls+lm)<=m)
{
t.ls=0;
t.lm=ls+lm;
t.step=step+1;
t.ln=ln;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
else
{
t.ls=ls-(m-lm);
t.lm=m;
t.step=step+1;
t.ln=ln;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
}
}
if(ln>0)
{
if(ls1
{
if((ls+ln)<=s)
{
t.ln=0;
t.ls=ls+ln;
t.step=step+1;
t.lm=lm;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
else
{
t.ln=ln-(s-ls);
t.ls=s;
t.step=step+1;
t.lm=lm;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
}
if(lm3
{
if((ln+lm)<=m)
{
t.ln=0;
t.lm=ln+lm;
t.step=step+1;
t.ls=ls;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
else
{
t.ln=ln-(m-lm);
t.lm=m;
t.step=step+1;
t.ls=ls;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
}
}
if(lm>0)
{
if(ls1
{
if((ls+lm)<=s)
{
t.lm=0;
t.ls=ls+lm;
t.step=step+1;
t.ln=ln;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
else
{
t.lm=lm-(s-ls);
t.ls=s;
t.step=step+1;
t.ln=ln;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
}
if(ln2
{
if((ln+lm)<=n)
{
t.lm=0;
t.ln=ln+lm;
t.step=step+1;
t.ls=ls;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
else
{
t.ln=n;
t.lm=lm-(n-ln);
t.step=step+1;
t.ls=ls;
if(vis[t.ln][t.lm]==0)
{
vis[t.ln][t.lm]=1;
pre[t.ln][t.lm]=ln*10+lm;
q.push(t);
}
}
}
}
}
/*for(int k=0;k<=5;k++)
{
for(int l=0;l<=5;l++)
{
cout<>s>>n>>m&&m+n+s!=0)
{
memset(pre,-1,sizeof(pre));
memset(vis,0,sizeof(vis));
if(s%2==0)
bfs();
else
cout<<"NO"<
N - Find a way
HDU - 2612
题目大意:给一个地图,有两个人Y和M,'@'代表KFC,'#'代表障碍,‘.’代表路,问找一个对于两个人来说都是最短的KFC
思路:先对Y做BFS记录所有Y到KFC的时间记录,然后对M做BFS
#include
#include
#include
using namespace std;
struct node
{
int x,y,step;
};
int st[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int n,m;
int vis[200+5][200+5];
int y1,y2,x1,x2;
char map[200+5][200+5];
int time[200+5][200+5];
int mint;
void bfs()
{
queueq;
node f,t;
int x,y,s;
f.x=x1;
f.y=y1;
f.step=0;
time[x1][y1]=0;
q.push(f);
while(!q.empty())
{
f=q.front();
q.pop();
x=f.x;
y=f.y;
s=f.step;
for(int i=0;i<4;i++)
{
t.x=x+st[i][0];
t.y=y+st[i][1];
t.step=s+1;
if(time[t.x][t.y]==-1&&t.x>=1&&t.x<=n&&t.y>=1&&t.y<=m&&map[t.x][t.y]!='#')
{
time[t.x][t.y]=t.step;
q.push(t);
}
}
}
return;
}
void bfsm()
{
queueq;
node f,t;
int x,y,s;
f.x=x2;
f.y=y2;
f.step=0;
vis[x2][y2]=0;
q.push(f);
while(!q.empty())
{
f=q.front();
q.pop();
x=f.x;
y=f.y;
s=f.step;
if(map[x][y]=='@'&&time[x][y]>=0)
{
if((time[x][y]*11+s*11)=0&&t.x>=1&&t.x<=n&&t.y>=1&&t.y<=m&&map[t.x][t.y]!='#'&&vis[t.x][t.y]==0)
{
vis[t.x][t.y]=1;
q.push(t);
}
}
}
cout<>n>>m)
{
mint=999999*11;
memset(time,-1,sizeof(time));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='Y')
{
x1=i,y1=j;
}
if(map[i][j]=='M')
{
x2=i,y2=j;
}
}
bfs();
bfsm();
}
return 0;
}
拖拖拉拉终于把专题一写完了。。后面的专题一定不会再多于一周了!!