2022 ICPC 南京 A

Stop, Yesterday Please No More

和很多题解不同的是 我记录的是袋鼠的左上和右下两个点
最后我们再用洞反向去吃袋鼠即可 这样问题就转化成了 一个规则矩形和一个路径相交
看到一个规则矩形我们马上反应到就是二位前缀和可以快速计算
然后就是这个路径起点我们定义为n m 即可 他最多就跑n-1那么远 不然一定就全部出界了
之后我们就枚举洞的起始坐标 因为在二维前缀和数组里洞是n m开始的 我们还要算 左上右下和起始坐标的相对差值再加上n m

void solve(){
    int n,m,k;cin>>n>>m>>k;
    int x1=1,y1=1,x2=n,y2=m;
    string s;cin>>s;
    for(auto i:s){
        if(i=='U'){
            x1=max(1ll,x1-1);
            if(x2==1){
                if(!k)cout<<n*m<<endl;
                else cout<<0<<endl;
                return;
            }
            x2=max(1ll,x2-1);
        }else if(i=='D'){
            if(x1==n){
                if(!k)cout<<n*m<<endl;
                else cout<<0<<endl;
                return;
            }
            x1=min(n,x1+1);
            x2=min(n,x2+1);
        }else if(i=='L'){
            y1=max(1ll,y1-1);
            if(y2==1){
                if(!k)cout<<n*m<<endl;
                else cout<<0<<endl;
                return;
            }
            y2=max(1ll,y2-1);
        }else if(i=='R'){
            if(y1==m){
                if(!k)cout<<n*m<<endl;
                else cout<<0<<endl;
                return;
            }
            y1=min(m,y1+1);
            y2=min(m,y2+1);
        }
    }
    int now=(x2-x1+1)*(y2-y1+1),x=n,y=m,f[2*n+1][2*m+1];
    memset(f,0,sizeof f);
    f[x][y]=1;
    for(int i=s.size()-1;i>=0;i--){
        if(s[i]=='U')x--;
        else if(s[i]=='D')x++;
        else if(s[i]=='L') y--;
        else y++;
        f[x][y]=1;
    }
    for (int i = 1; i <= n * 2 ; i++) for (int j = 1; j <= m * 2 ; j++) f[i][j] += f[i][j - 1];
    for (int i = 1; i <= n * 2 ; i++) for (int j = 1; j <= m * 2 ; j++) f[i][j] += f[i - 1][j];
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int x3=x1-i+n,y3=y1-j+m,x4=x2-i+n,y4=y2-j+m;
            int t=f[x4][y4]-f[x4][y3-1]-f[x3-1][y4]+f[x3-1][y3-1];
            if(t==now-k)ans++;
        }
    }
    cout<<ans<<endl;
}
posted @ 2023-01-12 16:39  ycllz  阅读(313)  评论(0)    收藏  举报