hdu 1401
hdu 1401 从昨天晚上就在做这道题了,orz,被坑了这么久,原因一直是MLE。。。。
欲哭无泪啊,改来改去,还是不能减少内存,后来,我发现其实我太二了,八维数组,我居然用的是int ,orz,难怪MLE,改成char 就不超了。。。
哎呀,得长记性了。。。。话说,这是我做的第一道DBFS,其实和BFS本质上还是一样的,就是多了一个判断,不过效率确实高了。。。orz。。。
还是直接贴代码了。。。
1 #include<iostream> 2 #include<algorithm> 3 #include<queue> 4 #include<cstring> 5 using namespace std; 6 7 char visited[8][8][8][8][8][8][8][8];//用来保存四个棋子的状态 8 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //上、下、左、右 9 10 struct point { 11 int x,y; 12 }; 13 struct node { 14 struct point p[4]; //一种状态,四个棋子 15 int step; 16 }; 17 //给棋排子序,避免同一个状态重复入队列 18 int cmp(const point &p,const point &q){ 19 if(p.x==q.x) 20 return p.y<q.y; 21 return p.x<q.x; 22 } 23 24 //判断是否可以走 25 int judge(node &s ,int i,int j,int flag){ 26 if( flag==1 ){ 27 if( s.step >=4 )//最多移动4步 28 return 0; 29 s.step ++; 30 } 31 s.p[i].x += dir[j][0]; 32 s.p[i].y += dir[j][1]; 33 if(s.p[i].x >= 0&&s.p[i].x < 8 &&s.p[i].y >=0&&s.p[i].y<8 ){ 34 int k; 35 for(k = 0 ; k< 4 ; k++){ 36 if( i!=k ){ 37 if( s.p[i].x== s.p[k].x&& s.p[i].y==s.p[k].y )//判断是否有点,有点的话,就间隔判断 38 if( flag==1 ) return judge(s ,i ,j, 0);//判断是否跳过相邻的点可以合法走动 39 else return 0; 40 } 41 } 42 //可以走 43 if( k>=4 ){ 44 sort(s.p,s.p+4,cmp); 45 return 1; 46 } 47 } 48 return 0; 49 } 50 51 void bfs(node s1,node s2){ 52 queue<node>Q1,Q2; 53 node ss; 54 Q1.push(s1),Q2.push(s2); 55 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'; 56 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'; 57 while((!Q1.empty())||(!Q2.empty())){ 58 if(!Q1.empty()){ 59 for(int i=0;i<4;i++){ 60 //第i个棋子,搜的方向//这是搜走一步的 61 for(int j=0;j<4;j++){ 62 ss=Q1.front(); 63 if(judge(ss,i,j,1)){ 64 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') 65 continue; 66 //在Q2中已经搜过 67 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'){ 68 printf("YES\n"); 69 return ; 70 } 71 Q1.push(ss); 72 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'; 73 } 74 } 75 } 76 Q1.pop();//出队列的时候一定要4颗棋子4个方向都试过才能出 77 } 78 if(!Q2.empty()){ 79 for(int i=0;i<4;i++){ 80 //第i个棋子,搜的方向//这是搜走一步的 81 for(int j=0;j<4;j++){ 82 ss=Q2.front(); 83 if(judge(ss,i,j,1)){ 84 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') 85 continue; 86 //在Q1中已经搜过 87 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'){ 88 printf("YES\n"); 89 return ; 90 } 91 Q2.push(ss); 92 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'; 93 } 94 } 95 } 96 Q2.pop(); 97 } 98 } 99 printf("NO\n"); 100 } 101 102 103 int main(){ 104 int x,y; 105 while(scanf("%d%d",&x,&y)!=EOF){ 106 node s1,s2; 107 s1.p[0].x=x-1,s1.p[0].y=y-1; 108 for(int i=1;i<4;i++){ 109 scanf("%d%d",&x,&y); 110 s1.p[i].x=x-1,s1.p[i].y=y-1; 111 } 112 for(int i=0;i<4;i++){ 113 scanf("%d%d",&x,&y); 114 s2.p[i].x=x-1,s2.p[i].y=y-1; 115 } 116 s1.step=s2.step=0; 117 sort(s1.p,s1.p+4,cmp); 118 sort(s2.p,s2.p+4,cmp); 119 memset(visited,0,sizeof(visited)); 120 bfs(s1,s2); 121 } 122 return 0; 123 }