搜索水題

      快要期末考試來了,最近也沒怎麼看算法,整理下我前段時間做的搜索超級水題吧,多做點搜索水題也算是爲以後學習圖論做點準備,baka哥說圖論的算法基本都是DFS和BFS。

POJ 1321 棋盤問題

鏈接:http://poj.org/problem?id=1321

代碼:

#include<cstdio>
#include<cstring>

char mapn[9][9];
int visit[9];//記錄列數是否相同
int n,k,tot;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};

void DFS(int a,int step)//a表示行號
{
	if(step==k)
	{
		tot++;
		return ;
	}
	if(a>=n)
		return ;
	for(int i=0;i<n;i++)
	{
		if(!visit[i]&&mapn[a][i]=='#')
		{
			visit[i]=1;
			DFS(a+1,step+1);
			visit[i]=0;
		}
	}
	DFS(a+1,step);  //第a+1行不放棋子的情況
}

int main()
{
	int i;
	while(scanf("%d%d",&n,&k)!=EOF)
	{
		if(n==-1&&k==-1)
			break;
		tot=0;
		memset(visit,0,sizeof(visit));
		for(i=0;i<n;i++)
			scanf("%s",mapn[i]);
		DFS(0,0);

		printf("%d\n",tot);
	}
	return 0;
}

		


 

HDU 1016  Prime RIng Problem 

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1016

代碼:

#include<cstdio>
#include<cstring>

int n;
int isp[40],visit[21],A[21];
bool is_prime(int m)
{

    if(m==2||m==3)
        return 1;
    for(int i=2;i*i<=m;i++)
        if(m%i==0)
        return 0;
    return 1;
}

void DFS(int cur)
{

    if(cur==n&&isp[A[0]+A[cur-1]])    //遞歸邊界
    {
        for(int i=0;i<n-1;i++)
            printf("%d ",A[i]);
        printf("%d\n",A[n-1]);
    }

    else
        for(int i=1;i<=n;i++)
    {

        if(!visit[i]&&isp[i+A[cur-1]])//如果i沒有用過,是否和相鄰的加起來是素數
        {

            A[cur]=i;
            visit[i]=1;
            DFS(cur+1);
            visit[i]=0;

        }
    }
}
int main()
{
    for(int i=2;i<=40;i++)
        isp[i]=is_prime(i);

    int k=1;
    while(scanf("%d",&n)!=EOF)
    {
        printf("Case %d:\n",k);
        memset(visit,0,sizeof(visit));
        A[0]=1;
        k++;

        visit[0]=1;
        visit[1]=1;
        DFS(1);
        printf("\n");

    }
       return 0;
}


 

HDU  1253勝利大逃亡

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1253

代碼:

#include<stdio.h>
#include<queue>
using namespace std ;

int a, b, c, T;
int map[51][51][51] ;
int dir[6][3] ={{1,0,0},{-1,0,0},{0,0,1},{0,0,-1},{0,1,0},{0,-1,0}};
struct node
{
    int x,y,z,step;
}start;

void BFS()
{
    queue<node> q ;
	node cur,next;

    start.x=0;
	start.y=0;
	start.z=0;
	start.step=0;

    map[0][0][0] = 1 ;
    q.push(start) ;

    while(!q.empty())
   {
        cur = q.front() ;
        q.pop() ;
        for(int i=0; i<6; i++)
        {
      
           next.x=cur.x+dir[i][0];
		   next.y=cur.y+dir[i][1];
		   next.z=cur.z+dir[i][2];

            if(next.x==a-1&&next.y==b-1&&next.z==c-1&&cur.step<=T)
            {
                printf("%d\n", cur.step+1) ;
                return ;
            }

            if(next.x>=0&&next.x<a&&next.y>=0&&next.y<b&&next.z>=0&&next.z<c&&!map[next.x][next.y][next.z])
            {
                map[next.x][next.y][next.z] = 1 ;
                next.step=cur.step+1;
                q.push(next) ;
            }
        }
    }
    printf("-1\n") ;
    return ;
}
int main()
{
    int t ;
    scanf("%d", &t) ;
    while(t--)
	{
        scanf("%d%d%d%d", &a, &b, &c, &T) ;
        for(int i=0; i<a; i++)
            for(int j=0; j<b; j++)
                for(int k=0; k<c; k++)
                    scanf("%d", &map[i][j][k]) ;

       if(map[a-1][b-1][c-1]||a+b+c-3>T)  //終點在牆上或者距離終點的最短距離大於要求時間
        {
            printf("-1\n") ;
            continue ;
        }
        if(a==1&&b==1&&c==1)
        {
            printf("0\n") ;
           continue ;
        }
        BFS() ;
    }
    return 0 ;
}


HDU 1312 Red and Black

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1312

代碼:

#include<cstdio>
#include<queue>

using std::queue;

int n,m;
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
char map[21][21];
struct point
{
	int x,y;
}start;
int num;

int BFS(int a,int b)
{
	int i;
	queue<point> q;
	point cur,next;

	start.x=a;
	start.y=b;

    q.push(start);
	num=1;
	while(!q.empty())
	{
		cur=q.front();
		q.pop();

		for(i=0;i<4;i++)
		{
			next.x=cur.x+dir[i][0];
			next.y=cur.y+dir[i][1];

			if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&map[next.x][next.y]!='#')
			{
				num++;
				map[next.x][next.y]='#';
				q.push(next);
			}
		}
	}
	return num;
}

int main()
{
	int i,j,si,sj;

	while(scanf("%d%d",&m,&n)!=EOF)
	{
		if(n==0&&m==0)
			break;

		getchar();
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				scanf("%c",&map[i][j]);
				if(map[i][j]=='@')
				{
					si=i;
					sj=j;
				}
			}
			getchar();
		}

		map[si][sj]='#';
		printf("%d\n",BFS(si,sj));
	}
	return 0;
}





 

HDU 2553 N皇后問題

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2553

數組記錄代碼:

#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)

using namespace std;
int n,tot;
int vis[3][22];

void dfs(int cur)
{
    if(cur==n) 
	{
		tot++;
		return ;
	}

    else
        for(int i=0; i<n; i++)
            if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]) //主對角線加n爲保證數組下標不小於0,小白書上有說明
            {
                vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
                dfs(cur+1);
                vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; 
            }
}
int main()
{

    int result[11];
    for(n=0; n<11; n++)    //在外邊打表,不然會超時
    {
        memset(vis,0,sizeof(vis));
        tot=0;
        dfs(0);
        result[n]=tot;
    }
    while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
	        break;
               printf("%d\n",result[n]);
	 }
    return 0;
}


 

直接DFS代碼:

#include<stdio.h>   
#include<string.h>   
#include<stdlib.h>   
int n,ans;  
int map[15];  
int visit[15];  
int sol[15];  
void dfs(int k)  
{  
	int i,j,flag;  
	if(k==n+1)  
	{  
		ans++;  
		return;  
	}  
	for(i=1;i<=n;i++)  
		if(!visit[i])  //各行棋子不能在同一豎   
		{  
			map[k]=i;  
			flag=1;  
			for(j=1;j<=k-1;j++)     
				if((abs(map[k]-map[j]))==abs((k-j))) //判斷是否在同一斜線上
				{  
					flag=0;  
					break;  
				}  
				if(flag)  
				{  
					visit[i]=1;  
					dfs(k+1);  
					visit[i]=0;  //釋放第i列,進行下一次搜索   
				}  
		}  
}  
int main()  
{  
	int i;  
	for(i=1;i<=10;i++)  
	{  
		ans=0;  
		n=i;  
		memset(map,0,sizeof(map));  
		memset(visit,0,sizeof(visit));  
		dfs(1);  
		sol[i]=ans;  
	}  
	while(scanf("%d",&n),n)  
		printf("%d\n",sol[n]);  
	return 0;  
}  


 HDU 1241 Oil Deposits

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1241 

這也是一道很水的BFS,只要找出相連的區域塊的數目就好。

代碼:

#include<iostream>
#include<cstdio>
#include<queue>

using namespace std;

int n,m;
char map[101][101];
int dir[8][2]={{0,1},{1,1},{1,0},{1,-1},{-1,1},{0,-1},{-1,0},{-1,-1}};

struct point
{
    int x,y;
}start;

void BFS(int a,int b)
{

    start.x=a;
    start.y=b;
    queue<point> q;
    int i;
    point cur,next;

    q.push(start);
    while(!q.empty())
    {
        cur=q.front();
        q.pop();

        for(i=0;i<8;i++)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];

            if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m)
            {
                if(map[next.x][next.y]=='@')
                {
                    map[next.x][next.y]='*';
                    q.push(next);
                }
            }
        }
    }
}

int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;

        int count=0;

        for(i=0;i<n;i++)
            scanf("%s",map[i]);

        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
            {
                if(map[i][j]=='@')
                {

                     map[i][j]='*';
                     BFS(i,j);
                     count++;
                }
            }

            printf("%d\n",count);
    }
    return 0;
}


HDU 1240 Asteroids

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1240

這是一道3維的BFS,在處理座標時注意點,基本就可以過了,跟普通的寬搜沒什麼兩樣。

代碼:

#include<cstdio>

#include<queue>

using namespace std;

struct  point

{

    int x,y,z,steps;

};

point start;
int dx,dy,dz;

int n;

char map[11][11][11];

int dir[6][3]={{1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}};

 

int bfs(point start)

{

    queue<point>q;

    int i;

    point cur,next;

    if(start.x==dx&&start.y==dy&&start.z==dz)//考慮起點和終點相同的情況

       return 0;

    start.steps=0;

    map[start.x][start.y][start.z]='X';

    q.push(start);

    while(!q.empty())

    {

       cur=q.front();//取隊首元素

       q.pop();

       for(i=0;i<6;i++) //廣度優先搜索

       {

           next.x=cur.x+dir[i][0];

           next.y=cur.y+dir[i][1];

           next.z=cur.z+dir[i][2];

           if(next.x==dx && next.y==dy && next.z==dz) //下一步就是目的地

            {

                return cur.steps+1;

            }

 

           if(next.x>=0&&next.x<n&&next.y>=0&&next.y<n&&next.z>=0&&next.z<n)//下一步不越界

              if(map[next.x][next.y][next.z]!='X') //下一步不是星星

              {

                  map[next.x][next.y][next.z]='X';

                  next.steps=cur.steps+1;

                  q.push(next);

              }

       }

    }

    return -1;

}

int main()

{

    char str[10];

    int i,j,step;

    while(scanf("START %d",&n)!=EOF)

    {
		getchar();

       for(i=0;i<n;i++)

	   {
           for(j=0;j<n;j++)

		   {
              for(int k=0;k<n;k++)
				  scanf("%c",&map[j][k][i]);
			  getchar();
		   }

	   }

       scanf("%d%d%d",&start.x, &start.y, &start.z);

       scanf("%d%d%d",&dx, &dy, &dz);

       scanf("%s",str);

       gets(str);

 

       step=bfs(start);

       if(step>=0)

          printf("%d %d\n",n,step);

       else

          printf("NO ROUTE\n");

    }

    return 0;

}

 

HDU1372 Knight Movies

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1372

這道題只要讀懂題目就很容易可以搞定,是棋盤上馬走的方向就是BFS搜索時的方向,棋盤是8*8,只不過用字母a到h表示。剛開始一直不明白題意,連樣例都沒看來,後來讀懂之後真是個超級大水題。嘻嘻,這道題寫的時候借用了下baka哥的頭文件,感覺酷酷的樣子,相信他不會怪我的吧,知道我這麼水,也寫不出什麼好的頭文件。吐舌頭

代碼:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;

int dir[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,-1},{-2,1}};
struct point
{
    int x,y;
    int step;
}start;
int dx,dy;
int visit[10][10];

int BFS(int x,int y)
{

    int i;
    queue<point> q;
    point cur,next;

    start.x=x;
    start.y=y;
    start.step=0;

    q.push(start);

    while(!q.empty())
    {

        cur=q.front();
        q.pop();

        if(cur.x==dx&&cur.y==dy)
            return cur.step ;

        for(i=0;i<8;i++)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];

            if(next.x>=0&&next.x<8&&next.y>=0&&next.y<8&&!visit[next.x][next.y])
            {
                visit[next.x][next.y]=1;
                next.step=cur.step+1;
                q.push(next);
            }
        }
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
   char a[3],b[3];
   int sx,sy,sum;
   while(scanf("%s%s",a,b)!=EOF)
   {
       printf("To get from %s to %s takes ",a,b);
       sx=a[0]-'a';
       sy=a[1]-'0'-1;
       dx=b[0]-'a';
       dy=b[1]-'0'-1;

       memset(visit,0,sizeof(visit));
       visit[sx][sy]=1;
       sum=BFS(sx,sy);

       printf("%d knight moves.\n",sum);

   }
   return 0;
}

 

 


 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章