1 条题解
-
0
自动搬运
来自洛谷,原作者为

kczno1
**搬运于
2025-08-24 21:49:18,当前版本为作者最后更新于2018-01-15 14:20:18,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
求出对于船的左上角,在哪些点是合法的,那么即可。(注意左上角有可能超出地图,即坐标有可能为负)
但要求船全部合法比较麻烦,可以只考虑各个边界的合法。
比如从上往下走时,就只用考虑移动后下边界的合法,因为其他的点都是和原来的船体重叠的。
考虑在处下边界合法就是,其中表示船体从左往右第列下边界的行,表示船宽。
那么枚举列,将其他列分别移动位再起来,就得到了这一列的答案。
用实现,时间
#include<bits/stdc++.h> using namespace std; template <typename T> void chmin(T &x,const T &y) { if(x>y)x=y; } template <typename T> void chmax(T &x,const T &y) { if(x<y)x=y; } typedef unsigned int ui; #define rep(i,l,r) for(int i=l;i<=r;++i) const int N=2000+5; int n,u; template <int N> struct BITSET { static const int U=N/32+2; ui a[U]; void set1(int x) { a[x/32]|=1<<(x&31); } bool operator [](int x) { return a[x/32]&(1<<(x&31)); } }; void or_left_move(ui *a,ui *b,int x)//a|=b<<x b[0..u] { int dk=x/32,dl=x&31; if(!dl) { rep(i,0,u)a[i+dk]|=b[i]; return ; } rep(i,0,u) { a[i+dk]|=b[i]<<dl; a[i+dk+1]|=b[i]>>32-dl; } } struct F { char s[N][N]; BITSET<N>a[N]; BITSET<N*2>cant[N*2]; int x0,y0;//left up int x1,y1;//right down int d[N]; void init() { x0=y0=n; rep(i,1,n) rep(j,1,n) if(s[i][j]=='X') a[j].set1(i); else if(s[i][j]=='r') { chmin(x0,i);chmin(y0,j); chmax(x1,i);chmax(y1,j); chmax(d[j],i); } rep(j,-n,n) rep(j2,max(1,j),min(n,j+y1-y0)) if(d[y0+j2-j]) or_left_move(cant[N+j].a,a[j2].a,N-(d[y0+j2-j]-x0)); } bool judge(int x,int y) { return !cant[N+y][x+1+N]; } }; F f[4];//f[0] judge if can move down;f[1] up;f[2] right;f[3] left; int g[N*2][N*2]; struct point { short x,y; }; point q[N*N*2*2];int tail; int dis; void out() { cout<<dis;exit(0); } void push(short x,short y) { q[++tail]=(point){x,y};g[N+x][N+y]=dis; } int main() { freopen("1.in","r",stdin);freopen("1.out","w",stdout); cin>>n;u=n/32; rep(i,1,n)scanf("%s",f[0].s[i]+1); rep(i,1,n) rep(j,1,n)f[1].s[n-i+1][n-j+1]=f[2].s[j][n-i+1]=f[3].s[n-j+1][i]=f[0].s[i][j]; rep(i,0,3)f[i].init(); memset(g,-1,sizeof(g)); push(f[0].x0,f[0].y0); rep(head,1,tail) { short x=q[head].x,y=q[head].y; dis=g[N+x][N+y]+1; if(g[N+x+1][N+y]==-1&&f[0].judge(x,y)) { if(x==n) out(); push(x+1,y); } int _x=x+f[0].x1-f[0].x0,_y=y+f[0].y1-f[0].y0; //(_x,_y) if(g[N+x-1][N+y]==-1&&f[1].judge(n-_x+1,n-_y+1)) { if(_x==1) out(); push(x-1,y); } //(_x,y) if(g[N+x][N+y+1]==-1&&f[2].judge(y,n-_x+1)) { if(y==n) out(); push(x,y+1); } //(x,_y) if(g[N+x][N+y-1]==-1&&f[3].judge(n-_y+1,x)) { if(_y==1) out(); push(x,y-1); } } puts("NIE"); }
- 1
信息
- ID
- 2545
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者