GMOJ 6841. 【2020.11.5提高組模擬】淘淘藍藍之樹 林
阿新 • • 發佈:2020-11-05
題目大意
題解
這種型別的題以前做過好多次了,但這題打了我一個考場的時間,但因為看錯了題還是錯了。
我的做法很簡單,可以發現對於一個樹林,可以在樹林上找到一個橫座標最大的點。
然後分別將這個點的右上方的點和其下面的點,左上方的點和其下面的點遮住,然後跑兩遍最短路,就能求出答案。
容易發現,這樣跑出來的兩遍最短路,圍成的圈一定包括整個樹林,然後這題就做完了。
程式碼
#include<cstdio> #include<cstring> #include<algorithm> #define N 2010 #define M N*N using namespace std; int n,m,i,j,k,map[N][N],data[M][3],ans,sx,sy,x,y,xx,yy,bz[N][N],dis[N][N],bzk[N][N],fx[10][3]; int xpl,ypl,xpr,ypr,sum,ii,jj,yp; char ch[N]; int main(){ freopen("forest.in","r",stdin); freopen("forest.out","w",stdout); scanf("%d%d\n",&n,&m); fx[1][1]=1;fx[1][2]=0; fx[2][1]=-1;fx[2][2]=0; fx[3][1]=0;fx[3][2]=1; fx[4][1]=0;fx[4][2]=-1; fx[5][1]=1;fx[5][2]=1; fx[6][1]=1;fx[6][2]=-1; fx[7][1]=-1;fx[7][2]=1; fx[8][1]=-1;fx[8][2]=-1; yp=1e9; xpl=1e9; for (i=1;i<=n;i++){ scanf("%s\n",ch+1); for (j=1;j<=m;j++){ if (ch[j]=='.') map[i][j]=1; if (ch[j]=='X'){ map[i][j]=2; if (i>xpr){ xpr=i; ypr=j; } if (i<xpl){ xpl=i; ypl=j; } yp=min(yp,j); } if (ch[j]=='*'){ map[i][j]=3; sx=i; sy=j; } } } ans=1e9; for (i=1;i<=n;i++) for (j=1;j<=m;j++) if (map[i][j]==2){ if (xpl==xpr&&sx==xpl){ ii=0;jj=1; data[1][1]=sx; data[1][2]=sy; memset(bz,0,sizeof(bz)); bz[sx][sy]=1; memset(dis,127,sizeof(dis)); dis[sx][sy]=0; while (ii<jj){ ii++; x=data[ii][1];y=data[ii][2]; for (k=1;k<=8;k++){ xx=x+fx[k][1];yy=y+fx[k][2]; if (xx<=n&&yy<=m&&xx>0&&yy>0&&map[xx][yy]!=2&&dis[xx][yy]>dis[x][y]+1){ dis[xx][yy]=dis[x][y]+1; if (bz[xx][yy]==0){ bz[xx][yy]=1; jj++; data[jj][1]=xx; data[jj][2]=yy; } } } } ans=dis[xpl][yp-1]*2; printf("%d\n",ans); return 0; } if (sx<xpr){ ii=0;jj=1; data[1][1]=sx; data[1][2]=sy; memset(bz,0,sizeof(bz)); bz[sx][sy]=1; memset(dis,127,sizeof(dis)); dis[sx][sy]=0; while (ii<jj){ ii++; x=data[ii][1];y=data[ii][2]; for (k=1;k<=8;k++){ xx=x+fx[k][1];yy=y+fx[k][2]; if (xx<=n&&yy<=m&&xx>0&&yy>0&&(yy<=ypr||xx<max(xpl,sx+1))&&map[xx][yy]!=2&&dis[xx][yy]>dis[x][y]+1){ dis[xx][yy]=dis[x][y]+1; if (bz[xx][yy]==0){ bz[xx][yy]=1; jj++; data[jj][1]=xx; data[jj][2]=yy; } } } } ans=dis[xpr+1][ypr]; ii=0;jj=1; data[1][1]=sx; data[1][2]=sy; memset(bz,0,sizeof(bz)); bz[sx][sy]=1; memset(dis,127,sizeof(dis)); dis[sx][sy]=0; while (ii<jj){ ii++; x=data[ii][1];y=data[ii][2]; for (k=1;k<=8;k++){ xx=x+fx[k][1];yy=y+fx[k][2]; if (xx<=n&&yy<=m&&xx>0&&yy>0&&(yy>=ypr||xx<max(xpl,sx+1))&&map[xx][yy]!=2&&dis[xx][yy]>dis[x][y]+1){ dis[xx][yy]=dis[x][y]+1; if (bz[xx][yy]==0){ bz[xx][yy]=1; jj++; data[jj][1]=xx; data[jj][2]=yy; } } } } ans+=dis[xpr+1][ypr]; printf("%d\n",ans); return 0; } ii=0;jj=1; data[1][1]=sx; data[1][2]=sy; memset(bz,0,sizeof(bz)); bz[sx][sy]=1; memset(dis,127,sizeof(dis)); dis[sx][sy]=0; while (ii<jj){ ii++; x=data[ii][1];y=data[ii][2]; for (k=1;k<=8;k++){ xx=x+fx[k][1];yy=y+fx[k][2]; if (xx<=n&&yy<=m&&xx>0&&yy>0&&(yy<=ypl||xx>min(xpr,sx-1))&&map[xx][yy]!=2&&dis[xx][yy]>dis[x][y]+1){ dis[xx][yy]=dis[x][y]+1; if (bz[xx][yy]==0){ bz[xx][yy]=1; jj++; data[jj][1]=xx; data[jj][2]=yy; } } } } ans=dis[xpl-1][ypl]; ii=0;jj=1; data[1][1]=sx; data[1][2]=sy; memset(bz,0,sizeof(bz)); bz[sx][sy]=1; memset(dis,127,sizeof(dis)); dis[sx][sy]=0; while (ii<jj){ ii++; x=data[ii][1];y=data[ii][2]; for (k=1;k<=8;k++){ xx=x+fx[k][1];yy=y+fx[k][2]; if (xx<=n&&yy<=m&&xx>0&&yy>0&&(yy>=ypl||xx>min(xpr,sx-1))&&map[xx][yy]!=2&&dis[xx][yy]>dis[x][y]+1){ dis[xx][yy]=dis[x][y]+1; if (bz[xx][yy]==0){ bz[xx][yy]=1; jj++; data[jj][1]=xx; data[jj][2]=yy; } } } } ans+=dis[xpl-1][ypl]; printf("%d\n",ans); return 0; } printf("%d\n",ans); return 0; }