CF1202C-题解

思路

观察 DDDWWW\tt DDDWWWWWWDDD\tt WWWDDD,发现结果没有区别。所以上下,左右不会相互影响,就可以考虑分别处理。

对于 DSAWWAW\tt DSAWWAW,分别处理就是 DAA,SWWW\tt DAA,SWWW

对于 DAA\tt DAA,记最开始在 00,路径就是:0,1,0,10,1,0,-1。最大值与最小值的差为 22,但自己占格子,经过的格子数量 33,可以得出,经过的格子数量为 mami+1ma-mi+1。(上下方向同样适用)

对于一个字符,处理后的坐标是在前一个的基础上 +1+1 或者 1-1。可以理解为前缀和。

WWDDD\tt WWDDD 前缀和后:

0 -1 -1 0 1 1 2

此时,我们要加入一个操作,也就是从 ii 开始的元素都会 +1+1 或者 1-1

最小值可能有很多个,区间为 [ml,mr][ml,mr],最大值的区间为 [mal,mar][mal,mar]

理想情况是 mr<malmr<mal 或者 mar<mlmar<ml,这样可以将长度减少 11

如果区间相交了,将最小值 +1+1,就必定会加上最大值,没用。将最大值 1-1,就必定会加上最小值,没用。

如果是 0,10,-1 这类,虽然符合,但事实上如果走了,最少也是两格。所以要特判下。

#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;
}
posted @ 2023-08-11 20:48  cjrqwq  阅读(21)  评论(0)    收藏  举报  来源