poj1817

自己的第一篇博客,希望能提升自己

http://poj.org/problem?id=1817

题意:有6x6的区域,有n辆车,车的尺寸有1x2,1x3,2x1,3x1,至少经过多少步使名叫‘x’的车从右边逃离这个区域,其中车子的移动不能转向,不能穿过车子,横着的只能横着走竖着的只能竖着走....

 

 

纠结了好久的BFS

 

 

题目分析:

利用BFS的基本方法,还是很暴力

 

代码……

#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <queue>
#include <cstring>
using namespace std;
int n;
char  grid[7][7];
map<const string,int>mp;
queue<string>q;

struct CAR
{
 int x;
 int y; //car的左上角坐标
 int a;
 int b;//car的尺寸
 int dir; //car的方向 1 -horizon 2 -vertical
 char na;
}car[12];
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};

void H1(int& a,int&b,int i,int j,int &l,int vis[7][7],char grid[7][7])
{
 char c=grid[i][j];
 for(int k=1;k<3;k++)
 {
  if(grid[i][j+k]==c){a++;l=1;vis[i][j+k]=1;}
  if(grid[i+k][j]==c){b++;l=2;vis[i+k][j]=1;}
 }

 return ;
}

void getcarinf(int n,char grid[7][7])
{
 int used[27]={0};
 int vis[7][7]={0};
 int cnt=0;
 for(int i=0;i<6;i++)
  for(int j=0;j<6;j++)
   if('.'==grid[i][j]||vis[i][j])continue;
   else if(grid[i][j]>='a'&&grid[i][j]<='z')
   {
    vis[i][j]=1;
    car[cnt].x=i;
    car[cnt].y=j;
    car[cnt].na=grid[i][j];
    H1(car[cnt].a,car[cnt].b,i,j,car[cnt].dir,vis,grid);
    cnt++;
   }
   return;
}

string getstate(char grid[7][7])
{
 string f="";

 for(int i=0;i<6;i++)
 {
  for(int j=0;j<6;j++)
   f+=grid[i][j];
 }
 return f;
}
void getgrid(const string& f,char g[7][7])
{
 memset(g,0,sizeof(g));
 for(int i=0;i<36;i++)g[i/6][i%6]=f[i];
 return;
}

bool ingrid(int i,int j,int w,int h,int type)
{

 if(i+w+dx[type]<0)return false;
 if(i+w+dx[type]>5)return false;
 if(j+h+dy[type]<0)return false;
 if(j+h+dy[type]>5)return false;
 return true;
}

int maxMove(char g[7][7],int i,int j,int w,int h,int type,char c,int w1,int h1,int step)
{


 
 //
 //最重要的部分
 //移动车子
 //方法比较啰嗦
 //type 表示车子移动方向 0left 1right 2up 3down
 //i,j车子的左上角坐标
 //w1,h1车子的wide height
 //w,h 移动车子时应考虑的偏移量……或许比较非主流的做法
 //


 char g1[7][7];
 for(int l=0;l<6;l++)strcpy(g1[l],g[l]);
 for(int k=1;k<6;k++)
  if(ingrid(i,j,w,h,type))
  { 
   int mx[]={i,i,i+h1,i};
   int my[]={j+w1,j,j,j};
   if(g1[i+w+dx[type]][j+h+dy[type]]=='.')
   {
    g1[i+w+dx[type]][j+h+dy[type]]=c;
    g1[mx[type]][my[type]]='.';
    string s1=getstate(g1);
    if(!mp[s1])
    {
     mp[s1]=step+1;
     q.push(s1);
    
    }
    
    i=i+dx[type];j=j+dy[type];
   }
   else break;

  }
  else break;
  for(int l=0;l<6;l++)strcpy(g[l],g1[l]);
  return 0;
 

}
int bfs(string state1)
{
 while(!q.empty())q.pop();
 mp.clear();
 int ok=0;
 q.push(state1);
 mp[state1]=1;
 char grid1[7][7];
 char grid2[7][7];

 int maxmove=0;
 while(!q.empty())
 {
  string u=q.front();
  q.pop();
  int step=mp[u];

  memset(car,0,sizeof(car));

  getgrid(u,grid2);
  getcarinf(n,grid2);
  for(int i=0;i<n;i++)
  {
   if('x'==car[i].na)
   {
    int ok1=1;
    if(car[i].dir==1)
    {
     getgrid(u,grid2);
     for(int ll=5;ll>car[i].y+car[i].a;ll--)if(grid2[car[i].x][ll]!='.')ok1=0;
     if(ok1)return step;
    }
    else
    {
     return -1;
    }
   }


   if(car[i].dir==1)
   {
    //left
    getgrid(u,grid1);
    maxMove(grid1,car[i].x,car[i].y,0,0,0,car[i].na,car[i].a,car[i].b,step);
    //right
    getgrid(u,grid1);
    maxMove(grid1,car[i].x,car[i].y,0,car[i].a,1,car[i].na,car[i].a,car[i].b,step);

   }
   if(car[i].dir==2)
   {
    //up
    getgrid(u,grid1);
    maxMove(grid1,car[i].x,car[i].y,0,0,2,car[i].na,car[i].a,car[i].b,step);
    //down
    getgrid(u,grid1);
    maxMove(grid1,car[i].x,car[i].y,car[i].b,0,3,car[i].na,car[i].a,car[i].b,step);

   }
  }


 }
 if(!ok)return -1;
}
int main()
{

 int kase=0;
 while(scanf("%d",&n)==1&&n)
 {
  memset(car,0,sizeof(car));
  for(int i=0;i<6;i++)scanf("%s",grid[i]);
  getcarinf(n,grid);

  string state=getstate(grid);

  int temp=bfs(state);
  if(temp<0)
   printf("You are trapped in scenario #%d.",++kase);
  else printf("Scenario #%d requires %d moves.",++kase,temp);
  printf("\n");


 }
 return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值