您的位置:首页 > 其它

hdu 1401

2013-01-28 11:56 225 查看
hdu 1401 从昨天晚上就在做这道题了,orz,被坑了这么久,原因一直是MLE。。。。


欲哭无泪啊,改来改去,还是不能减少内存,后来,我发现其实我太二了

,八维数组,我居然用的是int ,orz,难怪MLE,

改成char 就不超了。。。

哎呀,得长记性了。。。

。话说,这是我做的第一道DBFS,其实和BFS本质上还是一样的,就是多了一个判断,不过效率确实高了

。。。orz。。。

还是直接贴代码了。。。


#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;

char  visited[8][8][8][8][8][8][8][8];//用来保存四个棋子的状态
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};  //上、下、左、右

struct point {
int x,y;
};
struct node {
struct point p[4];  //一种状态,四个棋子
int step;
};
//给棋排子序,避免同一个状态重复入队列
int  cmp(const point &p,const point &q){
if(p.x==q.x)
return p.y<q.y;
return p.x<q.x;
}

//判断是否可以走
int judge(node &s ,int i,int j,int flag){
if( flag==1 ){
if( s.step >=4 )//最多移动4步
return 0;
s.step ++;
}
s.p[i].x += dir[j][0];
s.p[i].y += dir[j][1];
if(s.p[i].x >= 0&&s.p[i].x < 8 &&s.p[i].y >=0&&s.p[i].y<8 ){
int k;
for(k = 0 ; k< 4 ; k++){
if( i!=k ){
if(  s.p[i].x== s.p[k].x&& s.p[i].y==s.p[k].y )//判断是否有点,有点的话,就间隔判断
if( flag==1 ) return judge(s ,i ,j, 0);//判断是否跳过相邻的点可以合法走动
else return 0;
}
}
//可以走
if( k>=4 ){
sort(s.p,s.p+4,cmp);
return 1;
}
}
return 0;
}

void bfs(node s1,node s2){
queue<node>Q1,Q2;
node ss;
Q1.push(s1),Q2.push(s2);
visited[s1.p[0].x][s1.p[0].y][s1.p[1].x][s1.p[1].y][s1.p[2].x][s1.p[2].y][s1.p[3].x][s1.p[3].y]='1';
visited[s2.p[0].x][s2.p[0].y][s2.p[1].x][s2.p[1].y][s2.p[2].x][s2.p[2].y][s2.p[3].x][s2.p[3].y]='2';
while((!Q1.empty())||(!Q2.empty())){
if(!Q1.empty()){
for(int i=0;i<4;i++){
//第i个棋子,搜的方向//这是搜走一步的
for(int j=0;j<4;j++){
ss=Q1.front();
if(judge(ss,i,j,1)){
if(visited[ss.p[0].x][ss.p[0].y][ss.p[1].x][ss.p[1].y][ss.p[2].x][ss.p[2].y][ss.p[3].x][ss.p[3].y]=='1')
continue;
//在Q2中已经搜过
if(visited[ss.p[0].x][ss.p[0].y][ss.p[1].x][ss.p[1].y][ss.p[2].x][ss.p[2].y][ss.p[3].x][ss.p[3].y]=='2'){
printf("YES\n");
return ;
}
Q1.push(ss);
visited[ss.p[0].x][ss.p[0].y][ss.p[1].x][ss.p[1].y][ss.p[2].x][ss.p[2].y][ss.p[3].x][ss.p[3].y]='1';//在Q1中搜过的标记为'1';
}
}
}
Q1.pop();//出队列的时候一定要4颗棋子4个方向都试过才能出
}
if(!Q2.empty()){
for(int i=0;i<4;i++){
//第i个棋子,搜的方向//这是搜走一步的
for(int j=0;j<4;j++){
ss=Q2.front();
if(judge(ss,i,j,1)){
if(visited[ss.p[0].x][ss.p[0].y][ss.p[1].x][ss.p[1].y][ss.p[2].x][ss.p[2].y][ss.p[3].x][ss.p[3].y]=='2')
continue;
//在Q1中已经搜过
if(visited[ss.p[0].x][ss.p[0].y][ss.p[1].x][ss.p[1].y][ss.p[2].x][ss.p[2].y][ss.p[3].x][ss.p[3].y]=='1'){
printf("YES\n");
return ;
}
Q2.push(ss);
visited[ss.p[0].x][ss.p[0].y][ss.p[1].x][ss.p[1].y][ss.p[2].x][ss.p[2].y][ss.p[3].x][ss.p[3].y]='2';  //在Q2中搜过的标记为'2';
}
}
}
Q2.pop();
}
}
printf("NO\n");
}

int main(){
int x,y;
while(scanf("%d%d",&x,&y)!=EOF){
node s1,s2;
s1.p[0].x=x-1,s1.p[0].y=y-1;
for(int i=1;i<4;i++){
scanf("%d%d",&x,&y);
s1.p[i].x=x-1,s1.p[i].y=y-1;
}
for(int i=0;i<4;i++){
scanf("%d%d",&x,&y);
s2.p[i].x=x-1,s2.p[i].y=y-1;
}
s1.step=s2.step=0;
sort(s1.p,s1.p+4,cmp);
sort(s2.p,s2.p+4,cmp);
memset(visited,0,sizeof(visited));
bfs(s1,s2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: