Educational Codeforces Round 70 (Rated for Div. 2) C. You Are Given a WASD-string...(暴力枚举)

题意:给一个字符串序列包含{W,S,A,D}四个字符,分别表示在某一个初始位置向上下左右移动一个格子。

定义Grid(s)为 i一个包含所有所走位置的最小面积矩形。现在在该字符串上最多插入一个字符,问能构成的最小Grid(s)

 

思路:暴力枚举在第i个位置加上某个字符所能得到的答案,与ans取最min就可以了。

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
 
int suff[200050][4];
char s[200500];
int nowpos[2];
int maxv[4];
 
int main()
{
    int t;
    cin>>t;
 
    while(t--){
        scanf("%s",s+1);
        int n= strlen(s+1);
 
        int temp[4];
        for(int i=n;i;i--){
            temp[0] = temp[1] = temp[2] = temp[3] = 0;
            if(s[i]=='W'){
                temp[0]++;
            }
            else if(s[i]=='S'){
                temp[0]--;
            }
            else if(s[i]=='A'){
                temp[1]--;
            }
            else{
                temp[1]++;
            }
 
            suff[i][0] = max(suff[i+1][0]+temp[0] ,0 );
            suff[i][1] = max(suff[i+1][1]-temp[0] ,0 );
            suff[i][2] = max(suff[i+1][2]-temp[1] ,0 );
            suff[i][3] = max(suff[i+1][3]+temp[1] ,0 );
        }
 
        ll ans = 1<<30;
        ans *= ans;
 
        int x=0;
        int y=0;
 
        for(int i=0;i<=n;i++){
            if(s[i]=='W')   y++;
            else if(s[i]=='S')  y--;
            else if(s[i]=='A')  x--;
            else if(s[i]=='D')  x++;
 
            maxv[0] = max(maxv[0],y);
            maxv[1] = max(maxv[1],-y);
            maxv[2] = max(maxv[2],-x);
            maxv[3] = max(maxv[3],x);
 
            ll res = 1<<30;
            res *= 1<<30;
 
            if(suff[i+1][0] + y > maxv[0] ){
                ll h1 = suff[i+1][0] + y -1;
 
                int add=0;
                if(1+suff[i+1][1]-y>maxv[1]) add=1;
                ll h2 = max(suff[i+1][1] - y +add,maxv[1]);
                ll w1 = max(maxv[2],suff[i+1][2]-x);
                ll w2 = max(maxv[3],suff[i+1][3]+x);
 
                res = min(res, (w1+w2+1)*(h1+h2+1));
            }
            if(suff[i+1][1] - y > maxv[1] ){
                ll h1 = suff[i+1][1] - y -1;
                int add=0;
                if(1+suff[i+1][0]+y>maxv[0]) add=1;
                ll h2 = max(suff[i+1][0] + y +1,maxv[0]);
                ll w1 = max(maxv[2],suff[i+1][2]-x);
                ll w2 = max(maxv[3],suff[i+1][3]+x);
 
                res = min(res, (w1+w2+1)*(h1+h2+1));
            }
            if(suff[i+1][2] - x > maxv[2] ){
                ll h1 = max(suff[i+1][0] + y,maxv[0]);
                ll h2 = max(suff[i+1][1] - y,maxv[1]);
                ll w1 = suff[i+1][2]-x-1;
 
                int add=0;
                if(1+suff[i+1][3]+x>maxv[3]) add=1;
                ll w2 = max(maxv[3],suff[i+1][3]+x+add);
 
                res = min(res, (w1+w2+1)*(h1+h2+1));
            }
            if(suff[i+1][3] + x > maxv[3] ){
                ll h1 = max(suff[i+1][0] + y,maxv[0]);
                ll h2 = max(suff[i+1][1] - y,maxv[1]);
 
                int add=0;
                if(1-x+suff[i+1][2]>maxv[2]) add=1;
                ll w1 = max(maxv[2],suff[i+1][2]-x+add);
                ll w2 = suff[i+1][3]+x-1;
 
                res = min(res, (w1+w2+1)*(h1+h2+1));
            }
            ll h1 = max(suff[i+1][0] + y,maxv[0]);
            ll h2 = max(suff[i+1][1] - y,maxv[1]);
            ll w1 = max(maxv[2],suff[i+1][2]-x);
            ll w2 = max(maxv[3],suff[i+1][3]+x);
            res = min(res, (w1+w2+1)*(h1+h2+1));
 
            if(ans>res){
                //printf("res=%d i=%d\n",res,i);
            }
            ans = min(ans,res);
        }
 
        printf("%lld\n",ans);
 
        for(int i=0;i<n+10;i++){
            for(int j=0;j<4;j++){
                suff[i][j]=0;
            }
        }
        maxv[0] = maxv[1] = maxv[2] = maxv[3] = 0;
    }
 
 
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值