HDU 4444 - Walk
2012-11-08 11:51
267 查看
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4444
2012年ACMICPC金华赛区C题。
作为我们队主攻搜索和数据结构(线段树神马的经常接触离散化),当时我一看这题就有想法了,综合起来只敲了四十多分钟。(其间分身去把被卡了N久的水题A了)
我们队就是靠这题从铁直接飞到银牌。
思路很简单。
离散化边界为点。然后就是用普通的BFS去做。
需要储存每个边的四种状态:矩形上边界?矩形下边界?矩形左边界?矩形右边界?
边拐角的问题不同于角拐角,有六种可能,比较难解决,需要多一想一想。
比较难通过的是我附录的最后一组测试数据。
当时比赛时犯2,判断以EOF结束,WA了两次。。。 没想到,回来之后在HDU交,还是犯2,又判断以EOF结束,再WA两次。。。
2012年ACMICPC金华赛区C题。
作为我们队主攻搜索和数据结构(线段树神马的经常接触离散化),当时我一看这题就有想法了,综合起来只敲了四十多分钟。(其间分身去把被卡了N久的水题A了)
我们队就是靠这题从铁直接飞到银牌。
思路很简单。
离散化边界为点。然后就是用普通的BFS去做。
需要储存每个边的四种状态:矩形上边界?矩形下边界?矩形左边界?矩形右边界?
边拐角的问题不同于角拐角,有六种可能,比较难解决,需要多一想一想。
比较难通过的是我附录的最后一组测试数据。
当时比赛时犯2,判断以EOF结束,WA了两次。。。 没想到,回来之后在HDU交,还是犯2,又判断以EOF结束,再WA两次。。。
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> using namespace std; int x[110],y[110]; int idx[110],idy[110]; int mp[210][210],path[210][210]; bool UP[210][210],DOWN[210][210],LEFT[210][210],RIGHT[210][210]; int ax,ay,bx,by; int n,nn; int mx,my; struct QUE { int x,y; QUE() { } QUE(int xx,int yy) { x=xx,y=yy; } }que[200000]; int fx[]={1,0,0,-1,0,0,0,0,1,-1,1,-1}; int fy[]={0,1,-1,0,1,-1,1,-1,0,0,0,0}; int fz[]={0,0,0,0,1,1,-1,-1,-1,-1,1,1}; void turn(int ex,int ey,int rx,int ry,int &t,int p) { int i,nx,ny; for(i=1;;i+=2) { nx=rx+ex*i; ny=ry+ey*i; if(nx<0 || ny<0 || nx>mx || ny>my) { return; } if(mp[nx][ny]>0) { return; } if(i>1 &&(UP[nx-ex][ny-ey]&&DOWN[nx-ex][ny-ey]&&(ny&1) || (nx&1)&&LEFT[nx-ex][ny-ey]&&RIGHT[nx-ex][ny-ey])) { return; } if(path[nx][ny]==-1) { que[++t]=QUE(nx,ny); path[nx][ny]=p; } else if(path[nx][ny]<p) { return; } } } int bfs() { int s,t,k; int rx,ry; s=0; t=-1; for(k=0;k<4;k++) { turn(fx[k],fy[k],ax,ay,t,0); } while(s<=t) { rx=que[s].x; ry=que[s].y; ++s; for(k=0;k<4;k++) { if(rx+fx[k]==bx && ry+fy[k]==by) { return path[rx][ry]; } } if(rx&1) { for(k=4;k<8;k++) { if(UP[rx+fz[k]][ry]&&DOWN[rx+fz[k]][ry] || LEFT[rx+fz[k]][ry]&&RIGHT[rx+fz[k]][ry]) { if(fy[k]<0 && RIGHT[rx][ry] || fy[k]>0 && LEFT[rx][ry]) { continue; } } turn(fx[k],fy[k],rx+fz[k],ry,t,path[rx][ry]+1); } } else { for(k=8;k<12;k++) { if(UP[rx][ry+fz[k]]&&DOWN[rx][ry+fz[k]] || LEFT[rx][ry+fz[k]]&&RIGHT[rx][ry+fz[k]]) { if(fx[k]<0 && UP[rx][ry] || fx[k]>0 && DOWN[rx][ry]) { continue; } } turn(fx[k],fy[k],rx,ry+fz[k],t,path[rx][ry]+1); } } } return -1; } int cmpx(int a,int b) { return x[a]<x[b]; } int cmpy(int a,int b) { return y[a]<y[b]; } void discretization() { int i,tmp,now; nn+=2; for(i=0;i<nn;i++) { idx[i]=idy[i]=i; } sort(idx,idx+nn,cmpx); sort(idy,idy+nn,cmpy); tmp=-1000000000; now=0; for(i=0;i<nn;i++) { if(x[idx[i]]!=tmp) { tmp=x[idx[i]]; now+=2; } x[idx[i]]=now; } mx=now+2; tmp=-1000000000; now=0; for(i=0;i<nn;i++) { if(y[idy[i]]!=tmp) { tmp=y[idy[i]]; now+=2; } y[idy[i]]=now; } my=now+2; /* cout<<"离散化结果: "<<endl; cout<<"x: "; for(i=0;i<nn;i++) cout<<x[idx[i]]<<" ";cout<<endl; cout<<"y: "; for(i=0;i<nn;i++) cout<<y[idy[i]]<<" ";cout<<endl; */ nn-=2; ax=x[nn]; ay=y[nn]; bx=x[nn+1]; by=y[nn+1]; } void INIT() { int i,j,k; memset(mp,0,sizeof(mp)); memset(path,-1,sizeof(path)); memset(UP,0,sizeof(UP)); memset(DOWN,0,sizeof(DOWN)); memset(LEFT,0,sizeof(LEFT)); memset(RIGHT,0,sizeof(RIGHT)); for(i=0;i<n;i++) { for(j=x[i]+1;j<x[i+n];j++) { mp[j][y[i]+1]=mp[j][y[i+n]-1]=1; } for(j=y[i]+1;j<y[i+n];j++) { mp[x[i]+1][j]=mp[x[i+n]-1][j]=1; } for(j=x[i];j<=x[i+n];j++) { LEFT[j][y[i]]=true; RIGHT[j][y[i+n]]=true; } for(j=y[i];j<=y[i+n];j++) { DOWN[x[i]][j]=true; UP[x[i+n]][j]=true; } } /* cout<<"打印地图:"<<endl; for(j=my-1;j>=0;j--) { for(i=0;i<mx;i++) { // 2表示两点之间有不可走的边, 1表示两点之间有可走的边 , 0表示两点之间无边, .表示整数坐标点 if(i%2==0 && j%2==0) cout<<". "; else if(i%2==1 && j%2==1) cout<<" "; else if(mp[i][j] || UP[i][j]&&DOWN[i][j] || LEFT[i][j]&&RIGHT[i][j]) cout<<"2 "; else cout<<(UP[i][j]||DOWN[i][j]||LEFT[i][j]||RIGHT[i][j])<<" "; } cout<<endl; } */ } int input() { int i; int X1,X2,Y1,Y2; scanf("%d%d%d%d",&ax,&ay,&bx,&by); if(ax==0 && bx==0 && ay==0 && by==0) { return 0; } scanf("%d",&n); nn=n+n; for(i=0;i<n;i++) { scanf("%d%d%d%d",&X1,&Y1,&X2,&Y2); x[i]=min(X1,X2); x[i+n]=max(X1,X2); y[i]=min(Y1,Y2); y[i+n]=max(Y1,Y2); } x[nn]=ax; x[nn+1]=bx; y[nn]=ay; y[nn+1]=by; return 1; } int main() { while(input()) { discretization(); if(ax==bx && ay==by) { puts("0"); continue; } INIT(); printf("%d\n",bfs()); /* cout<<"打印路径:"<<endl; for(int i=my;i>=0;i--) { for(int j=0;j<mx;j++) { printf("%3d",path[j][i]); } cout<<endl; } */ } return 0; } /* // 绕路 2 1 1 1 4 1 0 2 2 3 // 直走 0 1 1 1 4 1 3 3 4 5 // 沿着边直走 0 0 1 0 7 2 0 2 2 3 -1 4 0 5 // 沿着边直走 0 0 1 0 7 2 0 2 2 3 0 3 2 4 // 无法穿过缝隙,绕路 2 0 1 0 7 2 0 2 2 3 -1 3 0 5 // 无法到达 -1 0 0 5 5 4 -1 1 1 2 1 -1 2 1 -1 -1 1 -2 -1 1 -2 -1 // 同点经过两次。 5 1 3 4 1 10 -1 -1 3 2 3 -1 7 0 7 -1 11 3 9 3 11 7 -1 7 11 9 0 5 4 7 -1 2 0 7 2 2 4 3 4 3 5 4 5 4 8 6 */
相关文章推荐
- HDU 4444 Walk(2012金华,搜索)
- HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典
- hdu 4444 Walk
- hdu 4444 Walk
- HDU 4444 Walk <离散化+找路径>
- hdu 4444 Walk(预处理+暴力)
- hdu 4444 Walk【2012 ACM/ICPC 金华区域赛C题】
- hdu 4444 Walk (离散化+建图+bfs+三维判重 好题)
- hdu 4444 Walk(离散化+BFS)
- HDU-1142-A Walk Through the Forest
- hdu 1142 A Walk Through the Forest【Dijkstra+dfs求最短路条数】
- HDU 5001 Walk
- HDU - 5001 Walk
- hdu 5001 Walk
- HDU - 5001 Walk(概率dp)
- HDU 1142 A Walk Through the Forest
- HDU 4758 Walk Through Squares(自动机+DP)
- HDU 1142 A Walk Through the Forest(SPFA+记忆化搜索DFS)
- HDU 1142 A Walk Through the Forest
- HDU 1142 A Walk Through the Forest(Dijkstra+Dfs(第一次用记忆化搜索))