poj1817
2014-04-07 16:03
204 查看
自己的第一篇博客,希望能提升自己
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;
}
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;
}
相关文章推荐
- Android开发之Instrumentation(自动化测试)
- css自动适应宽度
- rhel6修改Desktop分辨率
- 线段树 矩形并
- 一个用JS实现的简单的汉诺塔
- Deep Learning 学习 Toolbox学习记录三DenoisingAutoencoder
- 与她的第一次旅行
- 浅析android应用增量升级
- 图像通道与深度的理解
- Restore IP Addresses
- 2011斯坦福大学iOS应用开发教程学习笔记(第二课)My First iOS App
- 黑马程序员_Java中的面向对象小结
- gcc -fPIC
- SelectStockObject与SelectObject
- C++虚函数表解析
- RedHat Linux 5.5 x64系统NTP时钟服务器架设过程
- Android程序运行中动态加载Lib的方法
- Source Insight 的应用技巧
- 《算法导论》笔记 第6章 6.5优先级队列
- 《算法导论》笔记 第6章 6.5优先级队列