CF1202C-题解
思路
观察 和 ,发现结果没有区别。所以上下,左右不会相互影响,就可以考虑分别处理。
对于 ,分别处理就是 。
对于 ,记最开始在 ,路径就是:。最大值与最小值的差为 ,但自己占格子,经过的格子数量 ,可以得出,经过的格子数量为 。(上下方向同样适用)
对于一个字符,处理后的坐标是在前一个的基础上 或者 。可以理解为前缀和。
前缀和后:
0 -1 -1 0 1 1 2
此时,我们要加入一个操作,也就是从 开始的元素都会 或者 。
最小值可能有很多个,区间为 ,最大值的区间为 。
理想情况是 或者 ,这样可以将长度减少 。
如果区间相交了,将最小值 ,就必定会加上最大值,没用。将最大值 ,就必定会加上最小值,没用。
如果是 这类,虽然符合,但事实上如果走了,最少也是两格。所以要特判下。
#include<iostream>
#include<cstring>
using namespace std;
#define int long long
const int N = 2e5+10;
int T,ans,n;
char s[N];
int mi,ma;
void find(int a[],int&x,int&y) {
mi=0,ma=0;
mil=-1,mir=-1,mal=-1,mar=-1;
for(int i=1;i<=n;i++)
mi=min(mi,a[i]),ma=max(ma,a[i]);
for(int i=0;i<=n;i++) {
if(a[i]==mi&&mil==-1) mil=i;
if(a[i]==mi) mir=i;
if(a[i]==ma&&mal==-1) mal=i;
if(a[i]==ma) mar=i;
}
if(mir<mal||mar<mil) x=max(ma-mi,2LL);
else x=ma-mi+1;
y=ma-mi+1;
}
int a[N],b[N];
signed main() {
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>T;
while(T--) {
cin>>s+1;
n=strlen(s+1);
for(int i=1;i<=n;i++) {
a[i]=a[i-1],b[i]=b[i-1];
if(s[i]=='D') a[i]++;
if(s[i]=='A') a[i]--;
if(s[i]=='S') b[i]--;
if(s[i]=='W') b[i]++;
}
int x1=0,x2=0,y1=0,y2=0;
find(a,x1,x2),find(b,y1,y2);
cout<<min(x1*y2,x2*y1)<<"\n";
}
return 0;
}

浙公网安备 33010602011771号