您的位置:首页 > 其它

[BZOJ 4879][Lydsy2017年5月月赛]失控的数位板:模拟

2017-05-06 09:36 274 查看
点击这里查看原题

其实思路不难,对于每个点分三种情况。

没走过这个点,但却有颜色,无解

走过这个点,有颜色,那么最早时刻在最后一次经过该点之后

走过这个点,没有颜色,那么最晚时刻在最后一次经过该点之前

于是,将所有点加入set,倒序模拟一遍,依次删除所有走过的点,同时更新答案即可

/*
User:Small
Language:C++
Problem No.:4879
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=1e6+5;
int h,w,n,op[M],d[M],nex[4][2]={-1,0,0,1,1,0,0,-1},curx,cury;
ll t,L,R;
set<int> sx[M],sy[M];
char s[M];
int getop(char *s){
if(s[0]=='u') return 0;
if(s[0]=='r') return 1;
if(s[0]=='d') return 2;
if(s[0]=='l') return 3;
}
char ask(int x,int y,bool flag){
if(flag) swap(x,y);
return s[x*w+y];
}
void solve(set<int> &s,int st,int ed,ll tl,int wh,bool flag){
int l=st,r=ed;
if(l>r) swap(l,r);
for(set<int>::iterator it=s.lower_bound(l);it!=s.end()&&*it<=r;){
if(flag) sx[*it].erase(sx[*it].find(wh));
else sy[*it].erase(sy[*it].find(wh));
if(ask(wh,*it,flag)=='#') L=max(L,tl-abs(*it-st));
else R=min(R,tl-abs(*it-st)-1);
s.erase(it++);
}
}
int main(){
freopen("data.in","r",stdin);//
scanf("%d%d%d",&h,&w,&n);
for(int i=0;i<h;i++)
scanf("%s",s+i*w);
for(int i=1;i<=n;i++){
char tmp[10];
scanf("%s%d",tmp,&d[i]);
op[i]=getop(tmp);
}
for(int i=0;i<h;i++)
for(int j=0;j<w;j++) sx[i].insert(j);
for(int i=0;i<w;i++)
for(int j=0;j<h;j++) sy[i].insert(j);
curx=h-1;
cury=0;
t=1;
for(int i=1;i<=n;i++){
t+=d[i];
curx+=nex[op[i]][0]*d[i];
cury+=nex[op[i]][1]*d[i];
}
R=t;
for(int i=n;i;i--){
int tp=(op[i]+2)%4;
int nx=curx+nex[tp][0]*d[i],ny=cury+nex[tp][1]*d[i];
if(tp%2) solve(sx[curx],cury,ny,t,curx,0);
else solve(sy[cury],curx,nx,t,cury,1);
t-=d[i];
curx=nx;
cury=ny;
}
for(int i=0;i<h&&L<=R;i++){
for(set<int>::iterator it=sx[i].begin();it!=sx[i].end();it++){
if(ask(i,*it,0)=='#'){
L=R+1;
break;
}
}
}
if(L>R) L=R=-1;
printf("%lld %lld\n",L,R);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: