TYVJ搜索解题报告

BFS  poj2243马的遍历

链接地址:http://poj.org/problem?id=2243

#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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值