BFS poj2243马的遍历
链接地址:http://poj.o
#include<iostream>
#include<queue>
#include<cstring>
#define N 8
#define M 8
using namespace std;
int d[8][2]={-1,2, -2,1, -2,-1, -1,-2, 1,-2, 2,-1, 2,1, 1,2};//马跳的八个方向
int map[8][8],n,m,ans;
struct point{
int x,y,step;
}s,e;
int BFS(point s)
{
int i,x,y;
point t,temp;
queue <point> my;
while(!my.empty()) my.pop();//清空队列
my.push(s);
while(!my.empty())
{
t=my.front();
my.pop();
for(i=0;i<8;i++)
{
x=t.x+d[i][0];
y=t.y+d[i][1];
if(x==e.x && y==e.y) return t.step+1;//判断是否到达了目的坐标
if(x>=0 && x<N && y>=0 && y<M && !map[x][y])
{
temp.x=x;
temp.y=y;
temp.step=t.step+1;
map[x][y]=1;
my.push(temp);
}
}
}
}
int main()
{
char s1[N],s2[N];
while(cin>>s1>>s2)
{
s.x=s1[0]-97;
s.y=s1[1]-'1';
e.x=s2[0]-97;
e.y=s2[1]-'1';
memset(map,0,sizeof(map));
s.step=0;
if(s.x==e.x && s.y==e.y) ans=0;//判断始末节点是否相同
else ans=BFS(s);
cout<<"To get from "<<s1<<" to "<<s2<<" takes "<<ans<<" knight moves."<<endl;
}
return 0;
}
DFS(八皇后问题)
在棋盘上放置8个皇后,使得她们互不攻击,此时每个皇后的攻击范围为同行同列和同对角线,要求找出所有解。
皇后逐行放置,则皇后不会横向攻击,因此只需要检查是否纵向和斜向攻击就行了。条件(cur-c[cur==j-c[j] ) || (cur+c[cur]==j+c[j])用来判断皇后(cur,c[cur])和(j,c[cur])是否在
同一条对角线上。其原理可以用图1来说明。
格子(x,y)的y-x的值标识了主对角线
格子(x,y)的y+x的值标识了副对角线
利用二维数组map[2][]直接判断当前尝试的皇后所在的列和两个对角线是否已有其他皇后。注意主对角线标识y-x可能为负,存取时要加上n。
链接网址:http://tyvj.cn/Problem_Show.asp?id=1080
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
//int d[8][2]={0,1, -1,1, -1,0, -1,-1, 0,-1, 1,-1, 1,0, 1,1};
int n,tot,map[30][30],c[20];
void DFS(int cur)
{
int i,j;
if(cur == n) {//递归边界。只要走到这里,所有皇后必然不冲突
if(tot<3){
for(i=0;i<n-1;i++)
cout<<c[i]<<" ";
cout<<c[n-1]<<endl;
}
tot++;
}
else for(i=0;i<n;i++)
{
if(!map[0][i] && !map[1][cur+i] && !map[2][cur-i+n])
{//分别代表列,副对角线,主对角线
c[cur]=i+1;
map[0][i]=map[1][cur+i]=map[2][cur-i+n]=1;
DFS(cur+1);
map[0][i]=map[1][cur+i]=map[2][cur-i+n]=0;//改回来
}
}
}
int main()
{
int i;
while(cin>>n)
{
memset(map,0,sizeof(map));
memset(c,0,sizeof(c));
tot=0;
DFS(0);
cout<<tot<<endl;
}
return 0;
}
BFS tyvj1030乳草的侵入
链接网址:http://tyvj.cn/Problem_Show.asp?id=1030
提示注意草坐标的输入
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N=105;
int d[8][2]={0,1, -1,1, -1,0, -1,-1, 0,-1, 1,-1, 1,0, 1,1};
int n,m,num;
char map[N][N];
bool vis[N][N];
struct point
{
int x,y,step;
}p[N];
void BFS(point p)
{
int i,x,y,j,count=1;
point temp,t;
queue <point> my;
//memset(vis,false,sizeof(vis));
//vis[p.x][p.y]=true;
while(!my.empty()) my.pop();
my.push(p);
while(!my.empty())
{
t=my.front();
my.pop();
for(i=0;i<8;i++)
{
x=t.x+d[i][0];
y=t.y+d[i][1];
//&& !vis[x][y]
if(x>=0 && x<n && y>=0 && y<m && map[x][y]=='.' )
{
temp.x=x;
temp.y=y;
temp.step=t.step+1;
// vis[x][y]=true;
map[x][y]='*';
my.push(temp);
count++;
if(count==num){
cout<<temp.step<<endl;
return ;
}
}
}
}
}
int main()
{
int i,j;
point p;
while(cin>>m>>n>>p.y>>p.x)
{
p.x=n-p.x;
p.y=p.y-1;
p.step=0;
num=0;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
cin>>map[i][j];
if(map[i][j]=='.') num++;
}
//cout<<num<<" "<<p.x<<" "<<p.y<<endl;
map[p.x][p.y]='*';
BFS(p);
}
return 0;
}
/*
10 15 2 10
*.........
..........
..........
......*...
..........
......*...
..........
.......*..
..........
..........
..........
....*.....
..........
..........
..........
9
*/
BFS 分糖果
链接网址:http://tyvj.cn/Problem_Show.asp?id=1083
分析:用向量保存相邻的两条边再宽搜(遍历一遍即可),从c出发找到最远的一人,再加上m即可。
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=100010;
vector< int >G[MAX];
int step[MAX],cnt;
void BFS(int c)
{
int t,temp;
queue< int > my;
my.push(c);
while(!my.empty())
{
t=my.front();
my.pop();
int len=G[t].size();
for(int i=0;i<len;i++){
if(step[G[t][i]]==-1){
step[G[t][i]]=step[t]+1;
if(step[t]+1>cnt) cnt=step[t]+1;
my.push(G[t][i]);//G[t][i]表示与t相邻的第i个元素
//cout<<G[t][i]<<endl;
}
}
}
}
int main()
{
int n,p,c,m,i,a,b;
while(cin>>n>>p>>c>>m)
{
for(i=0;i<p;i++){
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
memset(step,-1,sizeof(step));
step[c]=cnt=0;
BFS(c);
cout<<cnt+m+1<<endl;
}
return 0;
}
/*
4 3 1
2
1 2
2 3
1 4
*/
DFS 计算细胞数
链接网址:http://tyvj.cn/Problem_Show.asp?id=1127
分析:扫描一遍,碰到非0的数,就DFS从他这里能找到非零数全都赋成0即可,同时答案+1.
对矩阵扫描完毕时得出的答案就是最终答案。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[100],a[10],map[51][81];
int n,m,d[4][2]={0,1, -1,0, 0,-1, 1,0};//经过的四个方向
int DFS(int x,int y)
{
for(int i=0;i<4;i++)
{
int nx=x+d[i][0];
int ny=y+d[i][1];
if(nx>=0 && nx<n && ny>=0 && ny<m && map[nx][ny]!='0')
{
map[nx][ny]='0';
DFS(nx,ny);
}
}
}
int main()
{
int i,j,ans;
while(gets(a)){
sscanf(a,"%d %d",&n,&m);
for(i=0;i<n;i++){
gets(map[i]);
}
ans=0;
/*************
for(i=0;i<n;i++){
for(j=0;j<m;j++)
cout<<map[i][j];
cout<<endl;
}
******************/
for(i=0;i<n;i++)
for(j=0;j<m;j++)
if(map[i][j]!='0'){
ans++;
map[i][j]='0';//将遍历过的置为'0'
DFS(i,j);
}
cout<<ans<<endl;
}
return 0;
}